├── README.md ├── hw1 ├── .gitignore ├── README.md ├── python │ ├── .gitignore │ ├── LICENSE.txt │ ├── NOTICE.txt │ ├── baby1994.html │ ├── babyname_parser.py │ └── run.py └── typescript │ ├── .gitignore │ ├── form.html │ ├── form.ts │ ├── images │ ├── fail_popup.png │ └── plain.png │ └── tsconfig.json ├── hw2 ├── .gitignore ├── README.md └── skeleton │ ├── .editorconfig │ ├── .gitignore │ ├── README.md │ ├── angular.json │ ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.e2e.json │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ └── in-memory-data.service.ts │ ├── assets │ │ └── .gitkeep │ ├── browserslist │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── karma.conf.js │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ ├── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ └── tslint.json │ ├── tsconfig.json │ └── tslint.json ├── hw3 ├── .gitignore ├── LICENSE ├── README.md ├── arc.pdf └── skeleton │ ├── blog │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── manage.py │ └── myblog │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── project ├── README.md ├── design-and-planning-examples └── Design_and_Planning_example.pdf ├── design-and-planning.md ├── postersession.md ├── project-requirements-and-specification.md ├── projectproposal.md ├── proposal-examples ├── Team1 - BusyWrite.pdf └── Team8 - You&Meet - X.pdf └── sprint-instructions.md /README.md: -------------------------------------------------------------------------------- 1 | # M1522.000100 Principles and Practices of Software Development 2 | 3 | ## Announcements 4 | 5 | - Team formation due 9/12 (Wed) 9pm 6 | - Project proposal due 9/19 (Wed) 9pm 7 | - Sep. 03 : Homework 1 is posted! 8 | - Sep. 06 : Skeleton code of Homework 1 python is updated (to import os package) 9 | - Sep. 07 : [Project guideline](project/README.md) is posted! 10 | - Sep. 19 : Homework 2 is posted! 11 | - Oct. 12 : Homework 3 is posted! 12 | - Oct. 22 : Sprint 2 report due is extended due to the Github service disruption. 13 | 14 | ## Assignments 15 | 16 | - Sep. 03 : [homework 1](hw1) is out 17 | - **Due : 9/21 (Fri) 20:59 (hard deadline)** 18 | - This is an individual assignment 19 | 20 | - Sep. 19 : [homework 2](hw2) is out 21 | - **Due : 10/12 (Fri) 23:59 (hard deadline)** 22 | - This is an individual assignment 23 | 24 | - Oct. 12 : [homework 3](hw3) is out 25 | - **Due : 11/2 (Fri) 20:59 (hard deadline)** 26 | - This is an individual assignment 27 | 28 | ## [Project Guideline](project) 29 | 30 | ## Schedule (TBD) 31 | | Week | Lecture | Practice Session | Homework / Project / Exam | 32 | |-------|---------|------------------|--------------------| 33 | |9/4,6 | Introduction - what softwares do, requirements and challenges to make them good, safe, and reliable | Environment setup | HW1 out | 34 | |9/11,13| How to collaborate as a team and the methods and tools for it | Git + GitHub practice with basic javascript + python coding examples | Team formation due 9/12 (Wed) 9pm; | 35 | |9/18,20 | Good coding habits. Comments and code conventions | Typescript + Front-end lecture (with a sample provided backend) | Project proposal due 9/19 (Wed) 9pm, HW 1 due 9/21 9pm | 36 | |9/25(추석),27 | Complexity problem and software structures | Typescript + Front-end lecture cont’d | Project sprint 1 begin (bi-weekly meetings with TAs at the end of sprint) | 37 | |10/2,4 | Complexity problem and software structures | | | 38 | |10/9,11 | Testing and throwing exceptions, Requirements and specification | Python + Creating backend for the created front-end from previous week | HW 2 due 10/12 11:59 pm, Project sprint 2 begin | 39 | |10/16,18 | Software development processes, Design patterns I | Python + Creating backend for the created front-end, Testing and CI | | 40 | |10/23,25 | Software structure and modeling | Design pattern practice 1 | Project sprint 3 begin | 41 | |10/30,11/1 | Code refactoring | Mid-project check | HW 3 due 11/2 9pm | 42 | |11/6,8 | Design patterns 2 | Design pattern practice 2, Code refactoring | Project sprint 4 begin | 43 | |11/13,15 | Design patterns 3 | Design pattern practice 3 | | 44 | |11/20,22 | Operation | Connecting DB and the backend, Performance layer | Project sprint 5 begin | 45 | |11/27,29 | Operation (load testing, security) | Scaling | Coding exams (2 hours) | 46 | |12/4,6 | Code optimization | | Project sprint 6 begin | 47 | |12/11,13 | TBD | | | 48 | |12/18 | Project poster session | | Project final report (due 12/20 8:59 pm) | 49 | 50 | ## Office hours 51 | **Professor** : 52 | - Office: Bldg. 302, Rm. 322 53 | - TuTh 11AM-12PM, by appointment 54 | 55 | **TAs** : 56 | 57 | Sanha Lee 58 | - Email: sanhaleehana@snu.ac.kr 59 | - Office: Bldg. 302, Rm. 420 60 | - Office hour: Tuesday 15:00~16:00 61 | 62 | Ahnjae Shin 63 | - Email: yuyupopo@snu.ac.kr 64 | - Office: Bldg. 302, Rm. 420 65 | - Office hour: Thursday 16:00~17:00 66 | 67 | Jae Hyeon Park 68 | - Email: skystar@snu.ac.kr 69 | - Office: Bldg. 302, Rm. 420 70 | - Office hour: Tuesday 17:00-18:00 71 | 72 | (Please send TAs an email ahead of time, we can set up a specific time and place) 73 | 74 | -------------------------------------------------------------------------------- /hw1/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | solution 3 | -------------------------------------------------------------------------------- /hw1/README.md: -------------------------------------------------------------------------------- 1 | # Homework 1 - Python and TypeScript Basics 2 | 3 | **Due: 9/21 (Fri) 20:59 (This is a hard deadline)** 4 | 5 | This assignment is for you to become familiar with Python and TypeScript. 6 | You will be using Python to build a backend system, and TypeScript will be used to build a (separated) frontend system, using the Angular2 framework. 7 | This is an **individual** assignment. 8 | 9 | From the beginning to the end of the development, you must use **GitHub** for version control. 10 | This will be used for your submission as well, so please keep it in mind. 11 | 12 | ## Python 13 | 14 | ### Objective 15 | In this assignment, you will implement an html file parser and find the common popular names for females and males in a year based on the skeleton code. 16 | You don't have to understand the implemented methods provided in the skeleton code, but studying them can be useful for your future term project. 17 | This is a modification of google's [Baby Names Python Exercise](https://developers.google.com/edu/python/exercises/baby-names). 18 | 19 | The goal of this assignment is to practice using various functions provided by the python language. 20 | In this assignment, you will get familiar with: 21 | 22 | - Built-in functions 23 | - Python provides many useful built-in functions. You can write code more efficiently and effectively if you are fluent with such functions. 24 | - Class 25 | - You will need to modularize and encapsulate your code to neatly manage your project. Class is a core concept to achieve such objectives. It is an important component in design patterns that you will learn in future classes. 26 | Since you will be defining your own models with classes in homework 3, you should be familiar with it. 27 | - Decorator 28 | - [Decorator](https://www.python.org/dev/peps/pep-0318/) is a special syntax in python for transforming functions using closure. It is also an important feature for applying design patterns in python, such as defining static methods or class methods. 29 | Many functions from Django are provided as decorators as well, especially with user authentication, which you will be using in homework 3. 30 | - Lambda function 31 | - Lambda function helps you write your python code in a functional programming style. In certain situations, functional style makes your code more concise and easy to modularize. 32 | For more information, read [Functional Programming HowTo](https://docs.python.org/3/howto/functional.html). 33 | 34 | ### 1. Implement `BabynameParser` 35 | You need to Implement the babyname parser class that parses the popular names and their ranks from an html file. 36 | In your skeleton code, `BabyParser` class is defined in `babyname_parser.py`. To complete the parser, you should implement the following functions: 37 | 38 | **1) `check_filename_existence`** 39 | 40 | At first, you need to implement a decorator that checks whether the file exists or not. 41 | This decorator will decorate the `__init__` of the parser to prevent constructing a parser with non-existing file name. 42 | This method should be implemented as a decorator in order to be easily applied to other methods. 43 | Please check out [this document](https://www.programiz.com/python-programming/decorator) to understand how to implement python decorator. 44 | 45 | For debuggability, defining your own exception and intentionally raising the exception is useful because you can identify the root cause of the exception and distinguish the exception from others. 46 | We provide `BabynameFileNotFoundException` for this purpose. 47 | If there is no such file with the given filename argument of the function to decorate, this decorator has to raise the custom `BabynameFileNotFoundException` with custom error message: `No such babyname file or directory: {filename}`. 48 | You can assueme that the `filename` argument is the first argument (right after the `self`) for the function to decorate. 49 | Also, we will not grade your decorator with it's stack trace but just test the class of the raised exception and it's message. 50 | 51 | For detailed information, check the execution example below. 52 | 53 | **2) `__init__`** 54 | 55 | This method is the constructor of the parser. In this method, you need to extract a list of the tuples of (rank, male-name, female-name) from the given html file. 56 | For your convinience, year extracting code is provided. You can refer the way to use regular expression in this code. 57 | 58 | **3) `parse`** 59 | 60 | This method applies a given lambda function to all of the extracted tuples and returns the results. 61 | 62 | **Usage** 63 | 64 | When you are done, you can parse any information about the popluar name ranks in a year by using the implemented parser. 65 | In the python console, you can test your code with the provided `baby1994.html` file like below. 66 | 67 | ``` 68 | >>> from babyname_parser import BabynameParser 69 | >>> parser = BabynameParser("baby1994.html") 70 | >>> parser.year 71 | '1994' 72 | >>> parser.rank_to_names_tuples 73 | [('1', 'Michael', 'Jessica'), ('2', 'Christopher', 'Ashley'), ('3', 'Matthew', 'Emily'), ...] 74 | >>> parser.parse(lambda rank_to_names_tuple: rank_to_names_tuple[0]) 75 | ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', ...] 76 | >>> BabynameParser("EmptyFileName") 77 | Traceback (most recent call last): 78 | File "", line 1, in 79 | File "/{YOUR_HW_PATH}/babyname_parser.py", line {EXCEPTION_RAISED_LINE}, in {DECORATOR_WRAPPER_NAME} 80 | raise BabynameFileNotFoundException("No such babyname file or directory: {0}".format(filename)) 81 | babyname_parser.BabynameFileNotFoundException: No such babyname file or directory: EmptyFileName 82 | ``` 83 | 84 | You should **NOT** edit parts other than those marked as `TODO`s in your skeleton code when you submit your assignment, because we will grade your `BabynameParser` implementation by not only running `run.py` file but also importing the class and test the methods like above (with different files and lambdas, of course). 85 | Also, the error message that comes out when the entered file does not exist must be 86 | `No such babyname file or directory: {filename}` and the result of `parse` method must be a list of all processed tuples. 87 | 88 | ### 2. Fill the run script 89 | 90 | In `run.py` file, a skeleton code using the parser is provided. 91 | Your task is to complete the code to parse an html file that contains the popular baby names in a year by using `BabynameParser`, sort them and find the common popular names with their rank. 92 | 93 | When you are done, the script must show results like below for the given `baby1994.html` file: 94 | 95 | ``` 96 | $ python solution/run.py baby1994.html 97 | Common popular babynames in 1994 (Count: 85) 98 | Common babyname: male rank, female rank 99 | Addison: 554, 800 100 | Adrian: 98, 834 101 | Alex: 50, 581 102 | Alexis: 227, 18 103 | Ali: 461, 674 104 | Angel: 104, 176 105 | Ariel: 480, 144 106 | Ashley: 957, 2 107 | ... 108 | ``` 109 | 110 | ## TypeScript 111 | 112 | ### How to run TypeScript programs 113 | 114 | 1. We assume that typescript is installed through npm: `$ npm install -g typescript` 115 | 2. With this set up, you can compile the typescript program as followings: `$ tsc`, under the directory you are working on. It will generate a new `form.js` file. 116 | 3. Validate that you have the newly generated `form.js` file, and you can use it in `form.html`, as provided in the skeleton code. In our case, you will simply need to open `form.html` on your favorite browser. 117 | 118 | Each of the files serve the following roles: 119 | 120 | - `form.html` : HTML file for layout for the form checking page. 121 | - `form.ts` : TypeScript file for form checking and using JS components. 122 | 123 | We provide `form.html` completely so you don't need to modify the file, but it would be helpful to know the contents for following HWs and your term project. 124 | You must only alter the code in the sections marked as TODO in the skeleton code and submit your code using GitHub. Do NOT alter the names of the forms in the provided HTML file. Refer to the HTML file to infer the form names. 125 | Also, please follow the instructions below, such as message format, to enable us to automatize the grading. If not, your homework may not be graded properly. 126 | 127 | To customize your compile option, please modify `tsconfig.json` file. For more detail, please check [tsconfig handbook](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). 128 | 129 | TIP: You will find `console.log()` function useful for printing and debugging. You will be able to access the console by using the developer tools and JavaScript console provided in each of the different browsers. 130 | 131 | ### TypeScript Form Checker 132 | 133 | To complete this assignment, you will have to implement a form checker, with tooltips, and modal pop-ups using TypeScript. Through this assignment, we expect you to be able to: 134 | 135 | - See usages of JavaScript/TypeScript 136 | - Try out basic and most common usages of JavaScript/TypeScript 137 | - Compare and learn the advantages of using TypeScript compared to JavaScript 138 | - Some taste of TypeScript before diving into Angular2 with HW2. 139 | 140 | When you just compile the skeleton typescript file and open `form.html`, you will see the following screen on your browser. 141 | 142 | ![Plain screen](typescript/images/plain.png) 143 | 144 | In here, each input box receives user's input. There are labels right after every input box but they are not presented because they don't have contents yet. 145 | If you push the "check" button, you will see an empty popup. 146 | 147 | You need to provide following features by completing `form.ts`: 148 | 149 | **1) form validation popup** 150 | 151 | With the given form, upon clicking on the `check` button, it should first produce a pop-up listing out which forms to check and correct (see requirements). 152 | If there is no problem with the form, it should show a modal indicating that it had been successfully submitted. 153 | Specific **requirements** are as listed below. 154 | - Email: characters@characters.domain (characters other than @ or whitespace followed by an @ sign, followed by more characters (not '@', '.', or whitespace: co.kr is not allowed in this case), and then a ".". After the ".", you can only write 2 to 3 letters from a to z). 155 | - Password: Must contain at least one number and one uppercase and one lowercase letter, and at least 8 or more characters. 156 | - Password Confirmation: Must match password. 157 | - Phone number: nnn-nnnn-nnnn: three numbers, then "-", followed by four numbers and a "-", then four numbers. 158 | - First name (English) : Start with a capital letter, followed by one or more lowercase letters. Should only contain alphabets (A-Z, a-z) 159 | - Last name (English) : Start with a capital letter, followed by one or more lowercase letters. Should only contain alphabets (A-Z, a-z) 160 | - Age : Must be a number between 0 and 200 (inclusive). 161 | - Birth date (Month) : Must be one of "January", "February", ..., "December" 162 | - Birth date (Day) : Must be a number of one or two digits. 163 | - Birth date (Year) : Must be a number between 1800 and 2018 (inclusive). 164 | 165 | If the form does not satisfy the requirements (for example, if Email, Password, and Password Confirmation fail), the alert message **must** be like: 166 | ``` 167 | You must correct: 168 | 169 | Email 170 | Password 171 | Password Confirmation 172 | ``` 173 | In here, the name of each entry of the validation failed input list must be identical with the name right after each `
` in the `form.html` like above. 174 | 175 | If the form satisfies the requirements, the alert message **must** be: 176 | ``` 177 | Successfully Submitted! 178 | ``` 179 | 180 | **2) correct label and tooltip** 181 | 182 | Even when closing the pop-up, it should tell once something is wrong with the form, with an 'X' icon next to each fields. Hovering the mouse over the icon should tell what is wrong with a tooltip like below. 183 | 184 | ![Fail labels](typescript/images/fail_popup.png) 185 | 186 | The error message in that tooltip **must** be identical with each requirement above. 187 | Also, if an entry becomes valid after another check, the 'X' label have to be disappeared. 188 | 189 | Tip: using regex might be useful for detecting wrong forms 190 | 191 | ## Grading 192 | 193 | ### Python (10 points) 194 | 195 | We will test your code under Python 3.6. 196 | 197 | - `check_filename_existence` decorator method in `babyname_parser.py` (2 points) 198 | - `parse` method in `babyname_parser.py` (4 points) (automatically include the `__init__` constructor) 199 | - `run.py` (4 points) 200 | - Partial points for minor errors 201 | 202 | ### TypeScript (10 points) 203 | 204 | We will grade the `form.ts` and `form.html` file under the `typescript` directory in your GitHub repository. 205 | We will see the outputs to validate your answers. 206 | We will compile your `form.ts` by running command `tsc` (version 3.0.3) with your `tsconfig.json` file. 207 | 208 | - Valid form checking with proper alert message (5 points) 209 | - Label (proper 'X') and modal tooltips (5 points) 210 | - Partial points for minor errors 211 | 212 | 213 | ## Submission 214 | 215 | Due: 9/21 (Fri) 20:59 (This is a hard deadline) 216 | 217 | You must create your own *private* repository under your account. 218 | **Be sure to add the TAs as collaborators in your repository settings!** (Detailed instructions below). 219 | We will check the snapshot of the *master* branch of your Github repository at the deadline and grade it. 220 | Please create a `python` and `typescript` folders, and put your homework files in them appropriately. 221 | Because there are many students in this class, we need to automatize the grading process, so your homework may not be graded properly if your directory hierarchy doesn't look like this: 222 | ``` 223 | repository_root/ 224 | README.md (this file) 225 | python/ 226 | baby1994.html 227 | babyname_parser.py 228 | run.py 229 | ... 230 | typescript/ 231 | form.html 232 | form.ts 233 | ... 234 | ``` 235 | Also, make sure to push your work on Github on time. 236 | 237 | ### Instructions on creating a private repository 238 | 239 | #### I. Get GitHub Student Developer Pack 240 | 241 | 1. Go to `https://education.github.com`. 242 | 2. Follow instructions to `Request a discount`. 243 | 244 | #### II. Make your private repository 245 | 246 | 1. Go to your github profile: `https://github.com/YOUR_USERNAME`. 247 | 2. Under `Repositories`, click on `New`. 248 | 3. Fill in `swpp-hw1-USERNAME` as your repository name, and mark is as `Private`. (e.g., `swpp-hw1-sanha`) 249 | 4. Hit `Create repository`. 250 | 5. In terminal, go to the directory that you will be working in (e.g., `~/workspace/swpp-hw1-USERNAME` or `~/swpp-hw1-USERNAME`) 251 | 6. Type in and run the following commands, which is also shown on the page that you will be looking at after step 4: 252 | 253 | ``` 254 | echo "# asdf" >> README.md 255 | git init 256 | git add README.md 257 | git commit -m "first commit" 258 | git remote add origin https://github.com/USERNAME/swpp-hw1-USERNAME 259 | git push -u origin master 260 | ``` 261 | 262 | 7. Under `Settings` then `Collaborators` tab, Add TAs as your collaborators: `sanha`, `yuyupopo`, and `skystar-p`. 263 | 8. You're all set! After finishing your homework, push your contents to your repository on time! 264 | -------------------------------------------------------------------------------- /hw1/python/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | __pycache__ 3 | -------------------------------------------------------------------------------- /hw1/python/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /hw1/python/NOTICE.txt: -------------------------------------------------------------------------------- 1 | Code for Google's Python Class 2 | Copyright 2010 Google Inc. 3 | 4 | This code developed by Nick Parlante 5 | at Google Inc, and modified by Sanha Lee 6 | at SNU Software Platform Lab 7 | for SWPP fall 2018 lecture. 8 | -------------------------------------------------------------------------------- /hw1/python/baby1994.html: -------------------------------------------------------------------------------- 1 | Popular Baby Names 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 21 | 27 | 28 | 29 |
15 | Social Security Online 16 | 17 | Popular Baby Names 18 |
22 | Popular Baby Names 23 | SSA logo: link to Social Security home page 26 |

Popular Names by Birth Year

September 12, 2007
30 | 31 |
32 | Background information 33 |


34 |   Select another ?
35 |

36 |   37 | 38 | 39 |  
40 |
41 |

Popularity in 1994

42 |

43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 |
RankMale nameFemale name
1MichaelJessica
2ChristopherAshley
3MatthewEmily
4JoshuaSamantha
5TylerSarah
6BrandonTaylor
7JacobBrittany
8DanielAmanda
9NicholasElizabeth
10AndrewMegan
11JosephNicole
12ZacharyKayla
13DavidRachel
14JamesLauren
15JohnStephanie
16RyanHannah
17AustinJennifer
18AnthonyAlexis
19WilliamVictoria
20JustinDanielle
21RobertAmber
22AlexanderCourtney
23JonathanJasmine
24KyleRebecca
25CodyMorgan
26KevinAlyssa
27ThomasBrianna
28AaronAlexandra
29JordanKelsey
30EricKatherine
31BenjaminMelissa
32DylanKimberly
33SamuelMichelle
34StevenAllison
35ChristianTiffany
36JoseHaley
37BrianMary
38AdamChelsea
39TimothyChristina
40NathanShelby
41RichardAnna
42PatrickAbigail
43CharlesSara
44SeanHeather
45JesseErin
46JasonLaura
47JeremyMaria
48MarkKaitlyn
49StephenAndrea
50AlexOlivia
51JuanJordan
52CameronMadison
53TravisMarissa
54TaylorBrooke
55JeffreyKristen
56DustinNatalie
57TrevorErica
58LuisKatelyn
59ConnorVanessa
60CalebShannon
61DevinMiranda
62EvanKelly
63JaredPaige
64PaulJacqueline
65KennethCrystal
66BryanCassandra
67HunterGabrielle
68GabrielBriana
69DakotaLindsey
70LoganKatie
71MitchellSierra
72CarlosAlexandria
73CoreyJulia
74IanMariah
75MarcusSydney
76GregoryEmma
77DerekAmy
78NathanielCaitlin
79ScottKathryn
80JesusJenna
81BlakeAngela
82GarrettSavannah
83BradleyAlicia
84EdwardBreanna
85DaltonCatherine
86ShawnDestiny
87PeterJamie
88AntonioMonica
89EthanBrittney
90SethErika
91LukeWhitney
92ShaneMadeline
93VictorKaitlin
94MiguelCaroline
95LucasAlexa
96TannerMolly
97SpencerSabrina
98AdrianDiana
99ErikCheyenne
100VincentMeghan
101DillonLeah
102CoryMackenzie
103IsaacGrace
104AngelChristine
105JakeCynthia
106AlejandroMargaret
107BrettLindsay
108JoelAngelica
109AlecMichaela
110GeorgeBianca
111ColeVeronica
112JorgeHolly
113EduardoKristina
114ChaseGabriela
115RaymondKristin
116CaseyBethany
117DevonAutumn
118WesleyCasey
119RicardoHailey
120FranciscoMelanie
121ColtonBrenda
122TroyBrandi
123OscarLisa
124ColinRachael
125MasonDesiree
126KeithKendra
127JackApril
128DominicKaren
129BrendanJulie
130ChadKathleen
131PhillipLeslie
132DonaldDominique
133ElijahNatasha
134JohnathanKara
135MartinPatricia
136DerrickHayley
137RonaldBailey
138CristianCarly
139XavierCassidy
140JulianKarina
141FrankSummer
142MarioTori
143ManuelAna
144AlanAriel
145OmarNancy
146HenryTara
147EdgarAlejandra
148AndreMarisa
149ClaytonClaire
150BryceCaitlyn
151GrantAdriana
152CollinRebekah
153JavierAlison
154JonathonKaylee
155DariusChloe
156DouglasRaven
157LeviJocelyn
158JeremiahKylie
159NoahValerie
160SergioGabriella
161HectorJade
162RobertoAudrey
163AndresKatrina
164NicolasKrystal
165JohnnyDeanna
166JacksonAriana
167GaryDana
168PhilipMikayla
169IsaiahMeagan
170CurtisDiamond
171DrewSandra
172IvanKassandra
173BradyJasmin
174FernandoBridget
175EdwinMonique
176HaydenAngel
177DennisDaisy
178CesarChelsey
179AllenKendall
180ZacheryAshlee
181RubenFelicia
182MaxwellKrista
183JalenJoanna
184MarcoKhadijah
185ErickSophia
186RandyYesenia
187MathewMallory
188BrentLydia
189TonyMercedes
190PedroJazmin
191MaxJillian
192PrestonMckenzie
193JerryKirsten
194RileyGina
195CalvinJazmine
196LarryPriscilla
197WyattCindy
198CraigMakayla
199RaulClaudia
200ColbyAlisha
201DarrenEvelyn
202RafaelAaliyah
203JefferyKiara
204CarlAnne
205RickyCierra
206LouisAshleigh
207TevinColleen
208JaimeCiara
209AlbertLacey
210JimmyAllyson
211KristopherTabitha
212TreyDenise
213MarcAbby
214SkylerBrandy
215DamianGuadalupe
216ChanceZoe
217ForrestEllen
218HarrisonFaith
219KalebMarina
220JulioCristina
221AlbertoLinda
222DallasIsabella
223SebastianNichole
224TrentonJaclyn
225ConnerKarla
226ArmandoAmelia
227AlexisJessie
228GageRosa
229EmmanuelMayra
230GerardoMeredith
231DannyCarolyn
232ZackaryMaggie
233MichealHope
234RussellAsia
235ShaquilleNaomi
236LawrenceClarissa
237DiegoHanna
238ParkerDaniela
239DominiqueCarmen
240JamalJustine
241TerryTessa
242AbrahamTatiana
243JoeIsabel
244RodneyWendy
245JonahKatlyn
246MicahTamara
247KodyMaya
248ArthurKasey
249LandonKiana
250DeandreAlexus
251WalterRaquel
252ToddBria
253MarcosAubrey
254BobbyCandace
255BillyTeresa
256GavinAshlyn
257LanceTiara
258AndyKelsie
259NolanCeleste
260AveryAlissa
261DonovanTheresa
262JayKatelynn
263NickolasBritney
264RogerKelli
265EnriqueNina
266JosueTyler
267RandallRenee
268TrentJacquelyn
269RamonCarolina
270BrandenGenesis
271JonRuby
272MorganCara
273ArturoSusan
274AlfredoHeidi
275TerranceCarrie
276JessieJordyn
277MalcolmMiriam
278DamienBrenna
279DevonteJanet
280MarvinEbony
281GustavoJenny
282MarquisArianna
283IsraelGloria
284GeraldToni
285JamieAshton
286MilesCecilia
287GiovanniCamille
288KendallTiana
289JohnathonEsther
290EddieCharlotte
291WillieCandice
292TheodoreMartha
293DamonMadeleine
294MauriceVirginia
295ReginaldAimee
296LorenzoTia
297LeeElena
298JosiahSavanna
299FrederickVivian
300SalvadorSelena
301DemetriusMarie
302DominickAngelina
303BryantImani
304ConorCarissa
305EliCassie
306ZackeryDakota
307RoyAdrianna
308MalikAlexia
309DevanteLogan
310QuintonLillian
311RossRuth
312MarshallDarian
313TyroneJanelle
314DeanMikaela
315CarsonSharon
316TommyHarley
317ErnestoMia
318EliasBarbara
319TyStacy
320ZachariahHelen
321TerrenceSadie
322DanteNikki
323HarleyKierra
324ShaunAnastasia
325ZaneTayler
326FabianKellie
327PabloHunter
328BrockNicolette
329BrennanStacey
330BruceShayla
331KelvinTierra
332DarrellElise
333WayneRobin
334ReneAlana
335DenzelCarla
336TerrellLiliana
337BrendenShawna
338JeromeAnnie
339DrakeRose
340FrancisValeria
341BradenAnn
342BrendonShanice
343QuentinCallie
344NelsonDevin
345SteveChristian
346MylesKarissa
347AngeloEva
348ChandlerMelinda
349FranklinLorena
350NeilPamela
351TuckerRiley
352MelvinKate
353LaneChelsie
354ClayPaola
355AshtonDeborah
356SimonBrianne
357DarianAdrienne
358GuillermoMelody
359DesmondAliyah
360LiamElisabeth
361RonnieTina
362OrlandoJustice
363TrevonSonia
364WestonLarissa
365DaleFrancesca
366MackenzieKylee
367DevanMarisol
368ByronJane
369LeonardTanya
370OliverChasity
371IsmaelDevon
372DarrylAlyson
373EugeneTania
374DaquanSasha
375KendrickEsmeralda
376LeonardoNatalia
377RomanKenya
378EstebanBreana
379EmilioKira
380EmanuelMacy
381KarlRegina
382GeoffreyAlaina
383DarienDonna
384KeeganMckenna
385StanleyBrooklyn
386WarrenDestinee
387KennyKristine
388RodolfoKali
389SaulLeticia
390ErnestLily
391FelixBryanna
392QuinnJosephine
393GrahamRandi
394KeenanJuliana
395BeauChristy
396StefanTracy
397ClintonKari
398SkylarMeaghan
399AbelPrecious
400CorbinMakenzie
401MoisesKyla
402SterlingPaula
403DavonSkylar
404GriffinSerena
405RayKyra
406KylerIndia
407JarrettMaranda
408DeshawnRachelle
409DwayneSelina
410GlennTaryn
411KurtCarley
412SamFrances
413WadeKaitlynn
414JoeyEmilee
415KameronSophie
416HarryTiffani
417CedricArielle
418HugoCiera
419AlvinAbbey
420FelipeIrene
421CarterShayna
422LeonAlice
423TylorCelina
424DavisCortney
425GilbertoKourtney
426JaquanJoy
427JermaineSylvia
428AllanKristy
429RashadBrittani
430ReidKailey
431JakobPeyton
432AlfonsoDaniella
433JordonAlma
434ElliotClara
435LukasKaila
436DaneCheyanne
437SheldonKayleigh
438CooperJohanna
439HaroldJaime
440AidanTanisha
441RudyJosie
442BraxtonMariana
443KristianKristi
444ReedChandler
445JarredSidney
446GilbertPayton
447MarquiseMaritza
448NoelElaine
449TyrellRobyn
450JavonAllie
451NikolasMichele
452TristanAnissa
453DemarcusCarina
454OwenChrista
455JarvisMadelyn
456ClarenceMarlene
457RamiroKiera
458RogelioJeanette
459ElliottMarilyn
460StephanAngelique
461AliCristal
462LeoNadia
463RolandoNoelle
464StuartJanae
465AlonzoYvette
466JusticeHaylee
467DarnellKatharine
468BrysonMicaela
469SawyerTasha
470TomasTrisha
471QuincyEricka
472BrodyLucy
473DeonTalia
474JarrodNora
475DonteLori
476AlfredBlanca
477CharlieElisa
478NigelHaleigh
479MarlonKatarina
480ArielChantel
481KeatonYvonne
482DeonteKaleigh
483KurtisIris
484ChrisAvery
485NoeDalia
486RoderickSimone
487LewisMargarita
488ClintJada
489RalphSofia
490TreViviana
491RodrigoParis
492JaysonCorinne
493GarretCarol
494BretEdith
495BernardLyndsey
496DamionMaribel
497BarryDesirae
498MitchelMoriah
499DerickKelley
500NathanaelStefanie
501TysonShaina
502BlaineGianna
503PaytonSusana
504ShannonAlanna
505AustenTianna
506KoryCasandra
507CliffordJudith
508MarkusLaurel
509SidneyMisty
510JuliusStephany
511SantiagoKadijah
512DuncanEmilie
513KellyItzel
514GraysonSandy
515BradDelaney
516EfrainCharity
517RaheemKaley
518EarlKelsi
519KirkPerla
520MauricioIvy
521MaximilianKiersten
522DequanTess
523HowardBridgette
524VicenteKennedy
525BabyLizbeth
526DarionAlexandrea
527LamarDallas
528DashawnYolanda
529HeathHallie
530KhalilBonnie
531DorianChanel
532StephonJill
533WilsonKassidy
534WalkerKaylin
535AhmadYasmin
536PerryKaylyn
537HumbertoJulianna
538ShelbyKathy
539AdanMollie
540DwightDiane
541IsiahNorma
542TyreeAlisa
543DionNia
544JaylenRochelle
545KareemLena
546PeytonJulianne
547CarltonAraceli
548DexterIsabelle
549DarylRocio
550AntoineAnita
551OsvaldoDorothy
552GordonLeanna
553TerenceBreanne
554AddisonBeatriz
555GunnarPaulina
556JaronCarlie
557MosesGenevieve
558ColtenLacy
559KaseyKarli
560UrielSuzanne
561AlvaroAlina
562LeroyJanice
563ChazSheila
564JuwanAlysha
565KoreyHalie
566AmirHillary
567CourtneyKelsea
568JaceKeri
569JamarAntoinette
570ShayneCharlene
571RolandKaylie
572NormanFatima
573SalvatoreRosemary
574BriceCayla
575GlenKatelin
576LonnieKarly
577BrentonSally
578LeonelShana
579AntonAshlie
580DarriusJacklyn
581DeionAlex
582DavonteCorina
583FredrickDawn
584MohammadEleanor
585FreddyZhane
586AdolfoRhiannon
587TravonMaegan
588BraydenNoemi
589IssacDulce
590TobyAshlynn
591DarrinSkyler
592CadeLexus
593ColemanEliza
594DimitriShirley
595SolomonKarlie
596DevenLea
597QuintinLucia
598JamelShelbi
599KentConnie
600CullenRoxanne
601DillanSade
602AgustinTonya
603FrankieJoyce
604HoldenJuanita
605CotySavanah
606KristoferMara
607ReynaldoNathalie
608JeanBeverly
609JoaquinEileen
610ConradKasandra
611DevontaMckayla
612NealRegan
613LloydGiselle
614MohammedRikki
615BenKarlee
616EzekielElaina
617MikeKeisha
618NathanialRyan
619EverettHeaven
620LamontYadira
621GuadalupeJesse
622AronShantel
623MiltonClare
624CortezReyna
625DandreAisha
626RigobertoKacie
627TracyAbbie
628KaneKalyn
629CorneliusShanna
630JadenKaty
631NestorBobbie
632HoustonCameron
633MalachiLoren
634ClarkKerri
635VernonBrook
636CliftonDarlene
637RickHailee
638ArnoldKori
639HakeemGeorgia
640IgnacioThalia
641MarcelKerry
642AhmedRebeca
643IrvinAnnette
644TateAngie
645BrooksYasmine
646DustyLuz
647DarinLucero
648DuaneBlair
649GerardLatisha
650DeangeloMontana
651RaphaelShauna
652FredMariela
653JaleelAlayna
654RickeyCora
655ColtTammy
656ForestLeanne
657ReeceTyra
658GermanJena
659TreverTabatha
660WillCarli
661ShaquanKatlin
662BennettSilvia
663BradfordBrittni
664LadariusJodi
665WinstonClarisa
666BrennenDarby
667GinoIesha
668JairoJustina
669JamisonAurora
670MohamedRita
671BernardoAntonia
672EzequielStacie
673HerbertKala
674JimmieAli
675KerryBeth
676RaymundoDemi
677ReubenChristie
678MadisonAyanna
679DonJanessa
680BrandynChristen
681EstevanSkye
682KieranBobbi
683AubreyCheryl
684KeonDebra
685RobinSonya
686HeribertoKiley
687JamesonStevie
688KadeMaureen
689ZechariahMyranda
690ThaddeusElla
691JovanTatyana
692AntwanCori
693JeffersonDenisha
694DillionJaqueline
695EzraOctavia
696AkeemCelia
697PierceEden
698RoryMadalyn
699CodeyLauryn
700DarrionBaby
701LorenJennie
702SammyHalle
703DylonKarley
704FreddieReagan
705ParisArlene
706UlisesMaura
707HassanBrandie
708ArronAspen
709CordellDevan
710JohnnieKristian
711JonasFabiola
712KadenJayme
713KolbyLatasha
714KaiMelina
715BrandanChristiana
716JeffDomonique
717MosheGwendolyn
718RashawnJenifer
719VaughnRacheal
720IrvingDestiney
721KhalidGladys
722DavionLara
723GeneLeigh
724SantosLesley
725CruzMicah
726JavonteCarlee
727LeslieHelena
728DakotahShea
729GonzaloMikala
730JasperAshly
731CadenJanie
732KoltonJoanne
733DonavanJoselyn
734StewartSarai
735JamarcusShyanne
736NicoKristyn
737PierreShelly
738GuyYazmin
739SageBreonna
740LesterBrionna
741ZakaryGretchen
742GradyKacey
743JackieShakira
744JamilDaphne
745DanaDestini
746DonnellBrittanie
747DonnieKrysta
748SheaYessenia
749RoyceAudra
750AugustAva
751DaytonAyana
752InfantDayana
753IsaiasHali
754JerrodHollie
755KeanuElyse
756NickMandy
757BenitoBetty
758BoDianna
759CamronMindy
760JadeLizette
761JaylonIngrid
762MyronKenia
763HermanKristie
764BradlyMaddison
765CyrusShelbie
766DarrianBrielle
767ErichEmerald
768BaileyKendal
769JabariKortney
770KevenAllyssa
771RhettBerenice
772CodieKirstin
773GarrisonJuana
774JarodJackie
775LincolnMaricela
776DeondreDanica
777ElvisEssence
778MontanaKianna
779ReeseDayna
780TobiasJalisa
781VanceJanette
782FloydMagdalena
783OctavioRoxana
784DevynGabriel
785GregorioJaimie
786JuniorJana
787FidelLynn
788ElmerSalina
789QuintenTrinity
790AlexandroAlesha
791AricJessika
792DaultonKaela
793ElishaLiana
794JosefShaniqua
795SavonJoelle
796AdonisTerri
797DewayneDevyn
798AsaSage
799DanStaci
800RicoAddison
801JamaalEllie
802BronsonGraciela
803CamdenTerra
804RockyBryana
805DarioMacey
806TraceKaterina
807AriStormy
808CristopherTricia
809JimZana
810TaylerAileen
811ErinLacie
812JoshAthena
813ToryAyla
814AndersonBelinda
815HughElissa
816JessyKailyn
817ShyheimPatrice
818StetsonPhoebe
819TyronCeline
820AustynElisha
821DeshaunJulissa
822DondreKailee
823JacobyAlysia
824RexDeja
825KelseyNadine
826EmmettSherry
827JustynTraci
828KadeemJudy
829LelandMaira
830MarkellJessi
831EfrenNataly
832MarquezMyra
833MenachemOlga
834TedAdrian
835UnknownAlycia
836CecilConstance
837KellenKalie
838MarkelBillie
839MisaelCatalina
840RasheedMarlena
841AltonMartina
842BlairBritany
843HarveyChristin
844JustusGriselda
845EllisLexi
846LionelMarisela
847MaximillianIvette
848AbramKaycee
849AmosKayley
850DallinScarlett
851EdgardoKaci
852JaydenAlessandra
853KhariBrea
854DawsonBreann
855DenverCecelia
856JevonJazmyn
857TyquanIrma
858RustyJami
859TrayvonKia
860NikoAustin
861SonnyTracey
862AlonsoAlysa
863DavinAsha
864HernanChantal
865MuhammadKeely
866AugustusElsa
867BennyKaylynn
868DaronPauline
869MikelAshanti
870RemingtonCorey
871SilasKenzie
872ValentinBeatrice
873WendellLayla
874AntonyNoel
875ClydeAlecia
876GunnerBridgett
877IbrahimDina
878KelbyKimberlee
879KevonLeandra
880NajeeSarina
881TalonIliana
882GalenJanay
883AsherLatoya
884BarrettMarlee
885JessAja
886JodyAshely
887JordenBailee
888DemetriMelisa
889DevontaeAnjelica
890LyleKatlynn
891AustonKayli
892CobySydnee
893MarquesHana
894OrionHaylie
895ShermanNikole
896AlexandreNohely
897RyneYaritza
898StormEboni
899TurnerLaken
900BryonLorraine
901CainMai
902DionteMarley
903KeganKimberley
904AldoMakenna
905AndreasTiffanie
906IsidroDamaris
907JaylinEmilia
908TitusFiona
909CristobalJamila
910GiancarloPrincess
911RandolphRylee
912DalvinMacie
913EdmundMarcella
914KeltonVanesa
915TraeDylan
916BrantMariam
917BroderickNikita
918CarloMaxine
919ChadwickAlena
920JerrellChaya
921KennedyJasmyn
922ChaimJoana
923DarrienTyesha
924DomenicAubree
925HansCarson
926LayneLyndsay
927RiverSusanna
928ChesterViridiana
929KendalGiovanna
930KentonEunice
931TavonPatience
932CodiKatheryn
933EliseoMonika
934JulienTiarra
935RodrickYasmeen
936UlyssesChantelle
937AlekKristal
938DestinLourdes
939KoleCydney
940MartyJoann
941OtisMattie
942TyrinRicki
943DarwinAleah
944JustenAmie
945SheltonGeneva
946KirbyLexie
947RandalMariel
948TariqDominque
949RyderTanesha
950DakodaChina
951DemarcoDenisse
952JacquesLeilani
953AxelLissette
954GregRhonda
955TyshawnShyann
956WilfredoDanyelle
957AshleyDrew
958CaleJerrica
959DemontePaloma
960MikalValentina
961SyedJanine
962SylvesterLaurie
963EliezerLeann
964SamsonLizeth
965ErvinBlake
966MaleKinsey
967NicklausKirstie
968PeteLeeann
969ShayMichael
970WaylonPorsha
971WestleyAndria
972DarrickJanell
973GarryLana
974DejuanMalia
975GenaroReina
976MaverickValencia
977MorrisCaitlynn
978SamirElyssa
979SchuylerJanel
980ArmaniJodie
981DemarioKathrine
982DeseanTatum
983EddyTiera
984GarettAdilene
985KahlilAnnamarie
986SpenserDarcy
987BrytonJean
988DontaeJessenia
989JeraldLondon
990JonatanBetsy
991LazaroDanika
992LutherIsis
993NikkoMari
994AbdulMarjorie
995BrannonEliana
996FrancescoFallon
997MickeyKallie
998DominqueLidia
999KenyonLynette
1000BlaiseMeranda
Note: Rank 1 is the most popular, 1050 | rank 2 is the next most popular, and so forth. 1051 |

1052 |
1053 | 1054 | 1055 | 1062 | 1063 |
 Link to FirstGov.gov: U.S. Government portal 1058 | Privacy Policy  1059 | | Website Policies 1060 | & Other Important Information  1061 | | Site Map
1064 | 1065 | -------------------------------------------------------------------------------- /hw1/python/babyname_parser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Copyright 2010 Google Inc. 3 | # Licensed under the Apache License, Version 2.0 4 | # http://www.apache.org/licenses/LICENSE-2.0 5 | 6 | # Google's Python Class 7 | # http://code.google.com/edu/languages/google-python-class/ 8 | 9 | # Modified by Sanha Lee at SNU Software Platform Lab for 10 | # SWPP fall 2018 lecture. 11 | 12 | import os 13 | import sys 14 | import re 15 | 16 | """Baby Names exercise 17 | 18 | Implement the babyname parser class that parses the popular names and their ranks from an html file. 19 | 20 | 1) At first, you need to implement a decorator that checks whether the html file exists or not. 21 | 2) Also, the parser should extract the tuples of (rank, male-name, female-name) from the file by using regex. 22 | For writing regex, it's nice to include a copy of the target text for inspiration. 23 | 3) Finally, you need to implement the parse(self, parsing_lambda) method that parses the extracted tuples 24 | with the given lambda and return the list of processed results. 25 | 26 | Here's what the html looks like in the baby.html files: 27 | ... 28 |

Popularity in 1990

29 | .... 30 | 1MichaelJessica 31 | 2ChristopherAshley 32 | 3MatthewBrittany 33 | ... 34 | """ 35 | 36 | 37 | class BabynameFileNotFoundException(Exception): 38 | """ 39 | A custom exception for the cases that the babyname file does not exist. 40 | """ 41 | pass 42 | 43 | 44 | def check_filename_existence(func): 45 | """ 46 | A decorator that catches the non-exiting filename argument and raises a custom `BabynameFileNotFoundException`. 47 | 48 | Args: 49 | func: The function to decorate. 50 | Raises: 51 | BabynameFileNotFoundException: if there is no such file named as the first argument of the function to decorate. 52 | """ 53 | # TODO: Implement this decorator. 54 | 55 | 56 | class BabynameParser: 57 | 58 | @check_filename_existence 59 | def __init__(self, filename): 60 | """ 61 | Given a file name for baby.html, extracts the year of the file and 62 | a list of the (rank, male-name, female-name) tuples from the file by using regex. 63 | [('1', 'Michael', 'Jessica'), ('2', 'Christopher', 'Ashley'), ....] 64 | 65 | Args: 66 | filename: The filename to parse. 67 | """ 68 | 69 | text = "File is not read yet" # TODO: Open and read the given file. 70 | # Could process the file line-by-line, but regex on the whole text at once is even easier. 71 | 72 | # The year extracting code is provided. Implement the tuple extracting code by using this. 73 | year_match = re.search(r'Popularity\sin\s(\d{4})', text) 74 | if not year_match: 75 | # We didn't find a year, so we'll exit with an error message. 76 | sys.stderr.write('Couldn\'t find the year!\n') 77 | sys.exit(1) 78 | self.year = year_match.group(1) 79 | 80 | # Extract all the data tuples with a findall() 81 | # each tuple is: (rank, male-name, female-name) 82 | self.rank_to_names_tuples = [] # TODO: Extract the list of rank to names tuples. 83 | 84 | def parse(self, parsing_lambda): 85 | """ 86 | Collects a list of babynames parsed from the (rank, male-name, female-name) tuples. 87 | The list must contains all results processed with the given lambda. 88 | 89 | Args: 90 | parsing_lambda: The parsing lambda. 91 | It must process an single (string, string, string) tuple and return something. 92 | Returns: 93 | The list of parsed babynames. 94 | """ 95 | # TODO: Implement this method. 96 | -------------------------------------------------------------------------------- /hw1/python/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Copyright 2010 Google Inc. 3 | # Licensed under the Apache License, Version 2.0 4 | # http://www.apache.org/licenses/LICENSE-2.0 5 | 6 | # Google's Python Class 7 | # http://code.google.com/edu/languages/google-python-class/ 8 | 9 | # Modified by Sanha Lee at SNU Software Platform Lab for 10 | # SWPP fall 2018 lecture. 11 | 12 | import sys 13 | from babyname_parser import BabynameParser 14 | 15 | """ 16 | Parse an html file that contains the popular baby names in a year, 17 | sort them and find the common popular names with their rank. 18 | 19 | Here's what the expected results looks like: 20 | Common popular babynames in 1994 (Count: 85) 21 | Common babyname: male rank, female rank 22 | Addison: 554, 800 23 | Adrian: 98, 834 24 | Alex: 50, 581 25 | Alexis: 227, 18 26 | ... 27 | """ 28 | 29 | 30 | def main(): 31 | # This command-line parsing code is provided. 32 | # Make a list of command line arguments, omitting the [0] element 33 | # which is the script itself. 34 | args = sys.argv[1:] 35 | 36 | if len(args) < 1: 37 | print('usage: python run.py filename') 38 | sys.exit(1) 39 | 40 | filename = args[0] 41 | parser = BabynameParser(filename) 42 | 43 | # Parse male-names and female-names from the file with the implemented parser. 44 | parsed_malenames = parser.parse(None) # TODO: Parse the rank and male-name tuples with your lambda. 45 | parsed_femalenames = parser.parse(None) # TODO: Parse the rank and female-name tuples with your lambda. 46 | 47 | # Find the common popular names. 48 | common_names = [] 49 | # TODO: Fill the common_names with (common popular babyname: male-rank, female-rank) strings. 50 | # TODO: Sort the list in ascending alphabetical order. 51 | 52 | # Print your result. 53 | print("Common popular babynames in {0} (Count: {1})".format(parser.year, str(len(common_names)))) 54 | print("Common babyname: male rank, female rank") 55 | for common_name in common_names: 56 | print(common_name) 57 | 58 | 59 | if __name__ == '__main__': 60 | main() 61 | -------------------------------------------------------------------------------- /hw1/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | form.js 2 | -------------------------------------------------------------------------------- /hw1/typescript/form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SWPP HW-1: Form checker 6 | 7 | 8 |
9 | Email: 10 | 11 |
12 | Password: 13 | 14 |
15 | Password Confirmation: 16 | 17 |
18 | Phone number: 19 | 20 |
21 | First Name: 22 | 23 |
24 | Last Name: 25 | 26 |
27 | Age: 28 | 29 |
30 | Birth Date: 31 |
32 | Month: 33 | 34 |
35 | Day: 36 | 37 |
38 | Year: 39 | 40 |
41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /hw1/typescript/form.ts: -------------------------------------------------------------------------------- 1 | class Form { 2 | constructor( 3 | public email: string, 4 | public password: string, 5 | public password_confirmation: string, 6 | public phone_number: string, 7 | public fname: string, 8 | public lname: string, 9 | public age: number, 10 | public birth_month: string, 11 | public birth_day: number, 12 | public birth_year: number) {} 13 | // TODO: You may fill in functions in the class. 14 | 15 | } 16 | 17 | var but = document.createElement('button') 18 | but.innerHTML = "Check" 19 | but.onclick = function() { 20 | var email : string = document.forms["form"]["email"].value 21 | // TODO: Fill in the rest of the function. Use the Form class defined above 22 | 23 | var form : Form 24 | 25 | let alertMessage = ''; 26 | // TODO: Fill the alert message according to the validation result by following the form in README.md. 27 | alert(alertMessage); 28 | 29 | // Hint: you can use the RegExp class for matching a string with the `test` method. 30 | // Hint: you can set contents of elements by finding it with `document.getElementById`, and fixing the `innerHTML`. 31 | // Hint: modify 'title' attribute of each label to display your message 32 | // Hint: Ask Google to do things you don't know yet! There should be others who have already done what you are to encounter. 33 | } 34 | document.body.appendChild(but) 35 | -------------------------------------------------------------------------------- /hw1/typescript/images/fail_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/hw1/typescript/images/fail_popup.png -------------------------------------------------------------------------------- /hw1/typescript/images/plain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/hw1/typescript/images/plain.png -------------------------------------------------------------------------------- /hw1/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "lib": ["es2016", "dom"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /hw2/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | solution 3 | -------------------------------------------------------------------------------- /hw2/README.md: -------------------------------------------------------------------------------- 1 | # Homework 2 - Angular Framework 2 | 3 | #### **Due: 10/12 (Fri) 23:59 (This is a hard deadline)** 4 | 5 | You will implement a front-end for a blogging service using Angular framework. This is an **individual** assignment. 6 | This assignment will help you 7 | 8 | - Make a simple Angular (version 6.1.0) application before diving into your projects 9 | - Let you try out stuff we have learned in our practice sessions 10 | 11 | ## Features 12 | 13 | Our blog will support three models: User, Articles, and Comments. 14 | For every requirements about HTML Tags in these tables, you **must** use the value of 'id' column as the "id" of the tag like 15 | `` 16 | You are required to create a total of five pages as shown in the below storyboard, meeting the following requirements: 17 | 18 | ![image](https://i.imgur.com/xDPo8Cl.png) 19 | 20 | - Sign In page (`/sign_in`) 21 | - You must have the following fields: 22 | 23 | | HTML Tag type | id | 24 | |---------------|--| 25 | | input | email-input | 26 | | input | pw-input | 27 | | button | signin-button | 28 | 29 | - Users should be able to sign-in by filling up the email and password inputs and hitting the sign-in button. 30 | - As we don't have a proper backend, we don't do real, security-aware authentication yet, but users should only be able to log in with an account with an email of 'swpp@snu.ac.kr' and password of 'iluvswpp'. 31 | - When a user tries to sign in with invalid inputs, the frontend should emit `Email or password is wrong` message through `alert` command (in Typescript). 32 | - After signing in, users should find themselves at the article list page. (`/articles`) 33 | - This is the only page that unauthorized users will have access to. Unauthorized users trying to access any other pages should be redirected to this page! (use '**'!) 34 | - Article list page (`/articles`) 35 | - Users should be able to clearly make out the **whole** list of articles including article id, (full) article title, and author name in this page. 36 | - Also, user must be able to go to article create page (`/articles/create`) by hitting: 37 | 38 | | HTML Tag type | id | 39 | |-------------|--| 40 | | button | create-article-button | 41 | 42 | - Upon clicking on the article title, users should be able to access the article's detail page (`/articles/:id`). These article titles must be `button` but not `link`. 43 | - Article write(create) page (`/articles/create`) 44 | - You must have the following fields in Write tab: 45 | 46 | | HTML Tag type | id | 47 | |-------------|--| 48 | | input or textarea | article-title-input | 49 | | input or textarea | article-content-input | 50 | | button | back-create-article-button | 51 | | button | confirm-create-article-button | 52 | | button (or maybe ngb-tab) | preview-tab-button | 53 | | button (or maybe ngb-tab) | write-tab-button | 54 | 55 | - Also, you must have the following fields in Preview tab: 56 | 57 | | HTML Tag type | id | 58 | |-------------|--| 59 | | any plain text (like h1, h3, p, …) | article-author | 60 | | any plain text (like h1, h3, p, …) | article-title | 61 | | any plain text (like h1, h3, p, …) | article-content | 62 | | button | back-create-article-button | 63 | | button | confirm-create-article-button | 64 | | button (or maybe ngb-tab) | preview-tab-button | 65 | | button (or maybe ngb-tab) | write-tab-button | 66 | 67 | - When users fill up the title and contents under Write tab and hit the confirm button (either in Preview tab or Write tab), a new article having the given title and contents should be posted. 68 | - The created article, of course, should be tagged with your own author id. 69 | - After creating the article, the user should be redirected to the created article's detail page (`/articles/:id`) 70 | - While creating the article, the user should be able to preview the contents (under the Preview tab by hitting `preview-tab-button`), in the way that it will be shown in the details page. The user should stay in `/articles/create` page while seeing the preview. 71 | - After checking the preview, the user should be able to resume writing (under the Write tab by hitting `write-tab-button`). The user should stay in `/articles/create` page after hitting the `write-tab-button`. 72 | - If the title and content input are empty, the confirm button should not react (don't post the new article nor make any alert). 73 | - The back button will go back to the article list page (`/articles`) (also without any alert). 74 | - Article detail page (`/articles/:id`) 75 | - You must have the following fields: 76 | 77 | | HTML Tag type | id | 78 | |-------------|--| 79 | | any plain text (like h1, h3, p, …) | article-author | 80 | | any plain text (like h1, h3, p, …) | article-title | 81 | | any plain text (like h1, h3, p, …) | article-content | 82 | | input or textarea | new-comment-content-input | 83 | | button | confirm-create-comment-button | 84 | | button | edit-comment-button | 85 | | button | delete-comment-button | 86 | | button | edit-article-button | 87 | | button | delete-article-button | 88 | | button | back-detail-article-button | 89 | 90 | - Users should be able to clearly make out the title, contents, and author name of the article. 91 | - Also, users should be able to see the whole comments for the corresponding article including the author name and contents of each comments. 92 | - Simple comments functionalities (Create for everyone / Edit/Delete for the comment author through the buttons) should work. 93 | - When a user hits the `confirm-create-comment-button`, a new comment with the contents provided through `new-comment-content-input` and the author's name should be added to this detail page (without any alert). 94 | - When a user hits the `edit-comment-button`, a `prompt` taking some string input should be popped up (by using Typescript `prompt` command). 95 | - When the user fill the prompt input with new contents and confirm the pop-up, the contents of the comment should be updated with the new contents. 96 | - When the user canceled the pop-up, the contents should not be modified. 97 | - When a user hits the `delete-comment-button`, the comment should be deleted without any alert. 98 | - The edit and delete button for each comment must be visible for the author only. 99 | - Edit/Delete button for the article should work. 100 | - These buttons must be visible for the author only. 101 | - When a user hit the `edit-article-button`, the user should be redirected to the edit page (`articles/:id/edit`) 102 | - When a user hit the `delete-article-button`, the user should be redirected to the article list page (`articles/`) and the article should be deleted without any alert. 103 | - When a user hits `back-detail-article-button` button, the user should be redirected to the article list page. 104 | - Article edit page (`/articles/:id/edit`) 105 | - You must have the following fields in Write tab: 106 | 107 | | HTML Tag type | id | 108 | |-------------|--| 109 | | input or textarea | article-title-input | 110 | | input or textarea | article-content-input | 111 | | button | back-edit-article-button | 112 | | button | confirm-edit-article-button | 113 | | button (or maybe ngb-tab) | preview-tab-button | 114 | | button (or maybe ngb-tab) | write-tab-button | 115 | 116 | - Also, you must have the following fields in Preview tab: 117 | 118 | | HTML Tag type | id | 119 | |-------------|--| 120 | | any plain text (like h1, h3, p, …) | article-author | 121 | | any plain text (like h1, h3, p, …) | article-title | 122 | | any plain text (like h1, h3, p, …) | article-content | 123 | | button | back-edit-article-button | 124 | | button | confirm-edit-article-button | 125 | | button (or maybe ngb-tab) | preview-tab-button | 126 | | button (or maybe ngb-tab) | write-tab-button | 127 | 128 | - Users should see similar stuffs with article create page: Write tab and Preview tab. All requirements for the plain texts and tab buttons are identical to the create page (except the url). 129 | - When a user hits `confirm-edit-article-button`, the user should be redirected to the article detail page (`articles/:id`) and the edited title and contents should be saved. Any comment for the article should not be modified or deleted by this process. 130 | - When a user hits `back-edit-article-button`, the following features should be supported: 131 | - If the title and contents have not been modified yet but are the same as the title and contents before editing, just go back to the detail page without any alert. 132 | - If the title or contents has been modified modified, you should make a confirmation pop-up (through Typescript `confirm` command) with message `Are you sure? The change will be lost.` 133 | - If the user accept the confirmation, the user should be redirected to the detail page and the title and contents of the article should not be modified. 134 | - If the user dismiss the confirmation, the user should just stay on the edit page and be able to resume editing. 135 | - Common things for all pages: 136 | - If the user is signed-in, the user should be able to sign out from any of the pages by clicking `signout-button`. Upon signing out, the user should end on the initial Sign In page (shown as dotted lines on the storyboard). 137 | 138 | | HTML Tag type | id | 139 | |---------------|--| 140 | | button | signout-button | 141 | 142 | - Each user should be able to update or delete articles and comments only which they have created. 143 | - ~**All pages/components should have proper unit tests to test its functionalities**, written in Jasmine, run by Karma (as shown in [this link](https://angular.io/guide/testing) and the practice session). Your tests are expected to cover all of your code, and we will give credits according to your coverage results. You can see the coverage information of your application as shown [here](https://www.angularonrails.com/add-test-coverage-report-angular-cli-project/). Also, all of your tests must pass.~ Due to the course schedule, you don't have to write your unit tests. You will be required to write unit tests for HW 3 instead. 144 | 145 | We provide a [in-memory mock backend](https://angular.io/tutorial/toh-pt6) with our skeleton code. 146 | Due to its simplicity, we do not go over too much into authentication and security for now, but later on (with HW3 and your project), it should be considered. 147 | 148 | You should be able to implement your service component by sending appropriate http requests to the following URLs: 149 | 150 | | API | GET | POST | PUT | DELETE | 151 | |------------------------|-----|------|-----|--------| 152 | | `api/user/:id` | Get user information containing whether or not the user is signed_in | X | Update user's `signed_in` value to sign-in/sign-out | X | 153 | | `api/articles` | Get article list | Create new article | | X | 154 | | `api/articles/:id` | Get specified article | X | Edit specified article | Delete specified article | 155 | | `api/comments` | Get comments | Create new comment | X | X | 156 | | `api/comments/:id` | Get specified comment | X | Edit specified comment | Delete specified comment | 157 | 158 | Articles should have an `id` (number), `author_id` (number), `title` (string), and `content` (string). 159 | Comments should have an `id` (number), `author_id` (number), `article_id` (number), and `content` (string). 160 | Users should have an `id` (number), `email` (string), `password` (string), `name` (string), and `signed_in` (boolean). 161 | 162 | Each field names are as specified above. You should be able to implement the pages required with these APIs. 163 | 164 | ## Comments on files 165 | 166 | Files that are created inside the `skeleton` (root) and `src` folder have been already discussed during the practice session (contents in [this link](https://angular.io/guide/quickstart#project-file-review)). You are not expected to create e2e tests just yet. We will score your homework with our own e2e tests. As we have done so in our practice sessions, you are expected to add components under the `src/app` directory freely, according to your needs. Nicely refactored code will result in better readability and is recommended. 167 | 168 | The `in-memory-data.service.ts` file is added to provide mock-backend for you to test out your application, and serves as specified above. **Please do not modify this file.** Under `src/app/*`, You are expected to create `Services` that communicate using HTTP, and `Components` that produce each pages meeting the requirements. The existing `AppCompoenent` is expected to be the root component of the entire application. 169 | Also, please do not make any un-requested alerts. It will largely harm the e2e test result. 170 | We will test your code after conducting `npm install`, so you can import other libraries through `package.json`. However, you should not change the version of already imported dependencies. 171 | 172 | ## Tips 173 | 174 | - Most of things have been covered in the tutorial during the lab session. Please look carefully through the slides and the tips provided. 175 | - It might be useful and more pleasing to the eyes by using a CSS framework like [Bootstrap](http://getbootstrap.com). However, this is optional, please proceed on your own willings. You might be needing them for your projects ahead, so it would be nice to have some head start. 176 | 177 | ## Grading 178 | 179 | This assignment is composed of a total of 55 points. 180 | We will score your code with our e2e test code, having 55 test cases that reflects the requirements given above. You will get 1 point for each passed test case. 181 | ~Also, we will check your unit test coverage. You will get 15 points if all of your unit tests pass and they cover your project entirely.~ 182 | 183 | The e2e test consist of cases about: 184 | - Sign in page features (4 cases) 185 | - Article list page features (5 points) 186 | - Article create page features (10 points) 187 | - Article detail page features when the user is the author of the article (14 points) 188 | - Article detail page features when the user is not the author of the article (13 points) 189 | - Article edit page features (9 points) 190 | 191 | Because we will automatically score your homework, please make sure that you followed the features specification (especially, the Tag type and id of HTML fields). 192 | Also, if some basic features are not implemented properly, many other test cases can fail. For example, if the signing-in process works badly, most of the cases above will fail. 193 | We'll try to give some partial points in this case, but it might not be enough. 194 | It's a good idea to start with the sign-in page, and then implement routing features, article list pages, and other features in order. 195 | 196 | ## Submission 197 | 198 | **Due: 10/12 (Fri) 23:59 (This is a hard deadline)** 199 | 200 | We will check the snapshot of the *master* branch of your Github repository at the deadline and grade it. 201 | Please name your repository as `swpp-hw2-YOUR_USERNAME`, and replace YOUR_USERNAME with you own GitHub username. 202 | Refer to HW1 to create another private repository. 203 | 204 | Please put your angular application files in the root folder (not inside another `hw2` or `skeleton` folder) appropriately. 205 | Your directory hierarchy should look like this: 206 | ``` 207 | repository_root/ 208 | README.md (this file) 209 | e2e/ 210 | ... 211 | src/ 212 | app/ 213 | assets/ 214 | environment/ 215 | ... 216 | package.json 217 | ... 218 | ``` 219 | 220 | Also, make sure to push your work on Github on time. You won't need to send us an email for submission, but we will pull each repositories at the time specified. 221 | -------------------------------------------------------------------------------- /hw2/skeleton/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /hw2/skeleton/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | yarn-error.log 34 | testem.log 35 | /typings 36 | 37 | # System Files 38 | .DS_Store 39 | Thumbs.db 40 | -------------------------------------------------------------------------------- /hw2/skeleton/README.md: -------------------------------------------------------------------------------- 1 | # SWPP-HW2 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.1.5. 4 | 5 | ## Comments on files 6 | 7 | Files that are created inside the `skeleton` (root) and `src` folder have been already discussed during the practice session (contents in [this link](https://angular.io/guide/quickstart#project-file-review)). You are not expected to create e2e tests just yet, but each `*.ts` files under your `src/app` directory should have corresponding `*.spec.ts` files that performs unit tests on your code. As we have done so in our practice sessions, you are expected to add components under the `src/app` directory freely, according to your needs. Nicely refactored code will result in better readability and is recommended. 8 | 9 | The `in-memory-data.service.ts` file is added to provide mock-backend for you to test out your application, and serves as specified above. Please do not modify this file. Under `src/app/*`, You are expected to create `Services` that communicate using HTTP, and `Components` that produce each pages meeting the requirements. The existing `AppCompoenent` is expected to be the root component of the entire application. 10 | 11 | ## Development server 12 | 13 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 14 | 15 | ## Code scaffolding 16 | 17 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 18 | 19 | ## Build 20 | 21 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 22 | 23 | ## Running unit tests 24 | 25 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 26 | 27 | ## Running end-to-end tests 28 | 29 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 30 | 31 | ## Further help 32 | 33 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 34 | -------------------------------------------------------------------------------- /hw2/skeleton/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "swpphw2": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "prefix": "app", 11 | "schematics": {}, 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:browser", 15 | "options": { 16 | "outputPath": "dist/swpphw2", 17 | "index": "src/index.html", 18 | "main": "src/main.ts", 19 | "polyfills": "src/polyfills.ts", 20 | "tsConfig": "src/tsconfig.app.json", 21 | "assets": [ 22 | "src/favicon.ico", 23 | "src/assets" 24 | ], 25 | "styles": [ 26 | "src/styles.css" 27 | ], 28 | "scripts": [] 29 | }, 30 | "configurations": { 31 | "production": { 32 | "fileReplacements": [ 33 | { 34 | "replace": "src/environments/environment.ts", 35 | "with": "src/environments/environment.prod.ts" 36 | } 37 | ], 38 | "optimization": true, 39 | "outputHashing": "all", 40 | "sourceMap": false, 41 | "extractCss": true, 42 | "namedChunks": false, 43 | "aot": true, 44 | "extractLicenses": true, 45 | "vendorChunk": false, 46 | "buildOptimizer": true 47 | } 48 | } 49 | }, 50 | "serve": { 51 | "builder": "@angular-devkit/build-angular:dev-server", 52 | "options": { 53 | "browserTarget": "swpphw2:build" 54 | }, 55 | "configurations": { 56 | "production": { 57 | "browserTarget": "swpphw2:build:production" 58 | } 59 | } 60 | }, 61 | "extract-i18n": { 62 | "builder": "@angular-devkit/build-angular:extract-i18n", 63 | "options": { 64 | "browserTarget": "swpphw2:build" 65 | } 66 | }, 67 | "test": { 68 | "builder": "@angular-devkit/build-angular:karma", 69 | "options": { 70 | "main": "src/test.ts", 71 | "polyfills": "src/polyfills.ts", 72 | "tsConfig": "src/tsconfig.spec.json", 73 | "karmaConfig": "src/karma.conf.js", 74 | "styles": [ 75 | "src/styles.css" 76 | ], 77 | "scripts": [], 78 | "assets": [ 79 | "src/favicon.ico", 80 | "src/assets" 81 | ] 82 | } 83 | }, 84 | "lint": { 85 | "builder": "@angular-devkit/build-angular:tslint", 86 | "options": { 87 | "tsConfig": [ 88 | "src/tsconfig.app.json", 89 | "src/tsconfig.spec.json" 90 | ], 91 | "exclude": [ 92 | "**/node_modules/**" 93 | ] 94 | } 95 | } 96 | } 97 | }, 98 | "swpphw2-e2e": { 99 | "root": "e2e/", 100 | "projectType": "application", 101 | "architect": { 102 | "e2e": { 103 | "builder": "@angular-devkit/build-angular:protractor", 104 | "options": { 105 | "protractorConfig": "e2e/protractor.conf.js", 106 | "devServerTarget": "swpphw2:serve" 107 | }, 108 | "configurations": { 109 | "production": { 110 | "devServerTarget": "swpphw2:serve:production" 111 | } 112 | } 113 | }, 114 | "lint": { 115 | "builder": "@angular-devkit/build-angular:tslint", 116 | "options": { 117 | "tsConfig": "e2e/tsconfig.e2e.json", 118 | "exclude": [ 119 | "**/node_modules/**" 120 | ] 121 | } 122 | } 123 | } 124 | } 125 | }, 126 | "defaultProject": "swpphw2" 127 | } 128 | -------------------------------------------------------------------------------- /hw2/skeleton/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './src/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: require('path').join(__dirname, './tsconfig.e2e.json') 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; -------------------------------------------------------------------------------- /hw2/skeleton/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('workspace-project App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('TODO: Finish up SWPP HW-2!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /hw2/skeleton/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /hw2/skeleton/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es6", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /hw2/skeleton/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "swpp-hw2", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animations": "^6.1.0", 15 | "@angular/common": "^6.1.0", 16 | "@angular/compiler": "^6.1.0", 17 | "@angular/core": "^6.1.0", 18 | "@angular/forms": "^6.1.0", 19 | "@angular/http": "^6.1.0", 20 | "@angular/platform-browser": "^6.1.0", 21 | "@angular/platform-browser-dynamic": "^6.1.0", 22 | "@angular/router": "^6.1.0", 23 | "angular-in-memory-web-api": "^0.6.1", 24 | "core-js": "^2.5.4", 25 | "http-server": "^0.11.1", 26 | "npm": "^6.4.1", 27 | "rxjs": "^6.0.0", 28 | "zone.js": "~0.8.26" 29 | }, 30 | "devDependencies": { 31 | "@angular-devkit/build-angular": "~0.7.0", 32 | "@angular/cli": "~6.1.5", 33 | "@angular/compiler-cli": "^6.1.0", 34 | "@angular/language-service": "^6.1.0", 35 | "@types/jasmine": "~2.8.6", 36 | "@types/jasminewd2": "~2.0.3", 37 | "@types/node": "~8.9.4", 38 | "codelyzer": "~4.2.1", 39 | "jasmine-core": "~2.99.1", 40 | "jasmine-spec-reporter": "~4.2.1", 41 | "karma": "^3.0.0", 42 | "karma-chrome-launcher": "^2.2.0", 43 | "karma-coverage-istanbul-reporter": "^2.0.4", 44 | "karma-jasmine": "^1.1.2", 45 | "karma-jasmine-html-reporter": "^0.2.2", 46 | "protractor": "~5.4.0", 47 | "ts-node": "~5.0.1", 48 | "tslint": "~5.9.1", 49 | "typescript": "~2.7.2" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /hw2/skeleton/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/hw2/skeleton/src/app/app.component.css -------------------------------------------------------------------------------- /hw2/skeleton/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | TODO: Finish up {{ title }}! 4 |

5 | Angular Logo 6 |
7 | 8 | -------------------------------------------------------------------------------- /hw2/skeleton/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | describe('AppComponent', () => { 4 | beforeEach(async(() => { 5 | TestBed.configureTestingModule({ 6 | declarations: [ 7 | AppComponent 8 | ], 9 | }).compileComponents(); 10 | })); 11 | it('should create the app', async(() => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.debugElement.componentInstance; 14 | expect(app).toBeTruthy(); 15 | })); 16 | it(`should have as title 'SWPP HW-2'`, async(() => { 17 | const fixture = TestBed.createComponent(AppComponent); 18 | const app = fixture.debugElement.componentInstance; 19 | expect(app.title).toEqual('SWPP HW-2'); 20 | })); 21 | it('should render title in a h1 tag', async(() => { 22 | const fixture = TestBed.createComponent(AppComponent); 23 | fixture.detectChanges(); 24 | const compiled = fixture.debugElement.nativeElement; 25 | expect(compiled.querySelector('h1').textContent).toContain('Finish up SWPP HW-2!'); 26 | })); 27 | }); 28 | -------------------------------------------------------------------------------- /hw2/skeleton/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | title = 'SWPP HW-2'; 10 | } 11 | -------------------------------------------------------------------------------- /hw2/skeleton/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | // Imports for loading & configuring the in-memory web api 5 | import { HttpClientModule } from '@angular/common/http'; 6 | import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api'; 7 | import { InMemoryDataService } from './in-memory-data.service'; 8 | 9 | import { AppComponent } from './app.component'; 10 | 11 | @NgModule({ 12 | declarations: [ 13 | AppComponent 14 | ], 15 | imports: [ 16 | BrowserModule, 17 | HttpClientModule, 18 | HttpClientInMemoryWebApiModule.forRoot( 19 | InMemoryDataService, { dataEncapsulation: false } 20 | ), 21 | ], 22 | providers: [], 23 | bootstrap: [AppComponent] 24 | }) 25 | export class AppModule { } 26 | -------------------------------------------------------------------------------- /hw2/skeleton/src/app/in-memory-data.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { InMemoryDbService } from 'angular-in-memory-web-api'; 3 | 4 | @Injectable() 5 | export class InMemoryDataService implements InMemoryDbService { 6 | 7 | createDb() { 8 | const articles = [ 9 | { id: 0, author_id: 1, title: 'The Past, Present, and Future of the Angular CLI', content: 'The Angular CLI is a command-line interface for building Angular applications, and over the last year it has become one of the most essential tools in an Angular developer’s toolbox.' }, 10 | { id: 11, author_id: 2, title: 'Taking Advantage of the Angular Material Datepicker', content: 'The datepicker is one of the newest components in Angular Material (added in May 2017). Our goal in creating the Angular Material datepicker is to create a datepicker that adheres to Material Design principles and is flexible enough to work across different applications and in different locales.' }, 11 | { id: 12, author_id: 1, title: 'The State of CSS in Angular', content: 'Styling applications is a critical part of delivering great experiences for users. Across the web we have Cascading Style Sheets (CSS) as a powerful standard for developers to define the look of an application separately from its construction.' }, 12 | { id: 13, author_id: 1, title: 'An Upgrade Path to Angular at Thomson Reuters', content: 'In the Tax & Accounting division of Thomson Reuters, we build software products for corporations, governments, accounting firms, financial institutions and more. We have a significant investment in AngularJS and Angular, and believe that migrating to the latest version is key to delivering the next generation of these products.' }, 13 | { id: 14, author_id: 3, title: 'Announcing NgRx 4', content: 'Of course, there is a lot more great stuff in this release (the improved dev ergonomics and error messages for starters). So check out the ngrx platform repository to find out more.' }, 14 | { id: 15, author_id: 2, title: 'Angular 4.3 Now Available', content: 'Angular version 4.3 has been released. This is a minor release following our announced adoption of Semantic Versioning, meaning that it contains no breaking changes and that it is a drop-in replacement for 4.x.x.' }, 15 | { id: 16, author_id: 2, title: 'Moving Quickly', content: 'The Angular CLI has made a lot of progress over the last few months, you can view the comprehensive notes about this progress on the releases page, but it can be helpful to look back on what’s happened in the last 4 months.' }, 16 | { id: 17, author_id: 2, title: 'Future of the CLI', content: 'The team working on the CLI has a lot of plans for making developers’ lives even easier. Here are a few of the ideas the team hopes to (but doesn’t promise to) include in future releases' }, 17 | { id: 18, author_id: 3, title: 'Component-Scoped CSS', content: 'Angular’s component model empowers developers to build in isolation as much as possible. This applies to styles as well, where unexpected side effects from CSS can be undesirable.' }, 18 | { id: 19, author_id: 3, title: 'Deep CSS', content: 'But what if I wanted to combine these two worlds? I want to write component-scoped CSS that affects the component itself as well as any children I put inside of it.' }, 19 | { id: 20, author_id: 3, title: 'Improved Testing', content: 'NgRx clearly separates the UI, state management, and side effects. This alone makes testing more straightforward and enjoyable, but we always knew we could do better.' } 20 | ]; 21 | const comments = [ 22 | { id: 0, article_id: 0, author_id: 1, content: 'Wow!' }, 23 | { id: 1, article_id: 0, author_id: 2, content: 'What do you mean wow?' }, 24 | { id: 2, article_id: 0, author_id: 3, content: 'I was surprised' }, 25 | { id: 3, article_id: 11, author_id: 1, content: 'Amazing!' }, 26 | { id: 4, article_id: 11, author_id: 3, content: 'I agree with you' }, 27 | { id: 5, article_id: 12, author_id: 3, content: 'Haha this is funny' }, 28 | { id: 6, article_id: 12, author_id: 2, content: 'Yes, it is hilarious' }, 29 | { id: 7, article_id: 13, author_id: 1, content: 'I am sad' }, 30 | { id: 8, article_id: 13, author_id: 2, content: 'I do not want to see you sad' }, 31 | { id: 9, article_id: 14, author_id: 3, content: 'I do not want to work' }, 32 | { id: 10, article_id: 15, author_id: 3, content: 'What time is it?' }, 33 | { id: 11, article_id: 15, author_id: 2, content: 'It is 5 in the morning' }, 34 | { id: 12, article_id: 16, author_id: 1, content: 'I like it' }, 35 | { id: 13, article_id: 17, author_id: 1, content: 'I do not think so' }, 36 | { id: 14, article_id: 17, author_id: 2, content: 'Me neither' }, 37 | { id: 15, article_id: 18, author_id: 2, content: 'I am so stressed out' }, 38 | { id: 16, article_id: 18, author_id: 3, content: 'Stress is bad' }, 39 | { id: 17, article_id: 18, author_id: 2, content: 'Yeah, I should try to feel better' }, 40 | { id: 18, article_id: 19, author_id: 1, content: 'My dog is cute' }, 41 | { id: 19, article_id: 19, author_id: 2, content: 'I think so as well' }, 42 | { id: 20, article_id: 20, author_id: 3, content: 'Tornado has hit our town' }, 43 | { id: 21, article_id: 20, author_id: 1, content: 'Oh, what a misery' } 44 | ]; 45 | const user = [ 46 | { id: 1, email: 'swpp@snu.ac.kr', password: 'iluvswpp', name: 'Software Lover', signed_in: false }, 47 | { id: 2, email: 'alan@turing.com', password: 'iluvswpp', name: 'Alan Turing', signed_in: false}, 48 | { id: 3, email: 'edsger@dijkstra.com', password: 'iluvswpp', name: 'Edsger Dijkstra', signed_in: false} 49 | ] 50 | return {articles, comments, user}; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /hw2/skeleton/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/hw2/skeleton/src/assets/.gitkeep -------------------------------------------------------------------------------- /hw2/skeleton/src/browserslist: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # 5 | # For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed 6 | 7 | > 0.5% 8 | last 2 versions 9 | Firefox ESR 10 | not dead 11 | not IE 9-11 -------------------------------------------------------------------------------- /hw2/skeleton/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /hw2/skeleton/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * In development mode, for easier debugging, you can ignore zone related error 11 | * stack frames such as `zone.run`/`zoneDelegate.invokeTask` by importing the 12 | * below file. Don't forget to comment it out in production mode 13 | * because it will have a performance impact when errors are thrown 14 | */ 15 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 16 | -------------------------------------------------------------------------------- /hw2/skeleton/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/hw2/skeleton/src/favicon.ico -------------------------------------------------------------------------------- /hw2/skeleton/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SWPP HW-2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /hw2/skeleton/src/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../coverage'), 20 | reports: ['html', 'lcovonly'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false 30 | }); 31 | }; -------------------------------------------------------------------------------- /hw2/skeleton/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /hw2/skeleton/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | // import 'core-js/es6/reflect'; 42 | 43 | 44 | /** Evergreen browsers require these. **/ 45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 46 | import 'core-js/es7/reflect'; 47 | 48 | 49 | /** 50 | * Web Animations `@angular/platform-browser/animations` 51 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 52 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 53 | **/ 54 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 55 | 56 | /** 57 | * By default, zone.js will patch all possible macroTask and DomEvents 58 | * user can disable parts of macroTask/DomEvents patch by setting following flags 59 | */ 60 | 61 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 62 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 63 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 64 | 65 | /* 66 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 67 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 68 | */ 69 | // (window as any).__Zone_enable_cross_context_check = true; 70 | 71 | /*************************************************************************************************** 72 | * Zone JS is required by default for Angular itself. 73 | */ 74 | import 'zone.js/dist/zone'; // Included with Angular CLI. 75 | 76 | 77 | 78 | /*************************************************************************************************** 79 | * APPLICATION IMPORTS 80 | */ 81 | -------------------------------------------------------------------------------- /hw2/skeleton/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /hw2/skeleton/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /hw2/skeleton/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "types": [] 6 | }, 7 | "exclude": [ 8 | "test.ts", 9 | "**/*.spec.ts" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /hw2/skeleton/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "test.ts", 12 | "polyfills.ts" 13 | ], 14 | "include": [ 15 | "**/*.spec.ts", 16 | "**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /hw2/skeleton/src/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /hw2/skeleton/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "module": "es6", 9 | "moduleResolution": "node", 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "target": "es6", 13 | "typeRoots": [ 14 | "node_modules/@types" 15 | ], 16 | "lib": [ 17 | "es2017", 18 | "dom" 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /hw2/skeleton/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs/Rx" 22 | ], 23 | "import-spacing": true, 24 | "indent": [ 25 | true, 26 | "spaces" 27 | ], 28 | "interface-over-type-literal": true, 29 | "label-position": true, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-arg": true, 47 | "no-bitwise": true, 48 | "no-console": [ 49 | true, 50 | "debug", 51 | "info", 52 | "time", 53 | "timeEnd", 54 | "trace" 55 | ], 56 | "no-construct": true, 57 | "no-debugger": true, 58 | "no-duplicate-super": true, 59 | "no-empty": false, 60 | "no-empty-interface": true, 61 | "no-eval": true, 62 | "no-inferrable-types": [ 63 | true, 64 | "ignore-params" 65 | ], 66 | "no-misused-new": true, 67 | "no-non-null-assertion": true, 68 | "no-shadowed-variable": true, 69 | "no-string-literal": false, 70 | "no-string-throw": true, 71 | "no-switch-case-fall-through": true, 72 | "no-trailing-whitespace": true, 73 | "no-unnecessary-initializer": true, 74 | "no-unused-expression": true, 75 | "no-use-before-declare": true, 76 | "no-var-keyword": true, 77 | "object-literal-sort-keys": false, 78 | "one-line": [ 79 | true, 80 | "check-open-brace", 81 | "check-catch", 82 | "check-else", 83 | "check-whitespace" 84 | ], 85 | "prefer-const": true, 86 | "quotemark": [ 87 | true, 88 | "single" 89 | ], 90 | "radix": true, 91 | "semicolon": [ 92 | true, 93 | "always" 94 | ], 95 | "triple-equals": [ 96 | true, 97 | "allow-null-check" 98 | ], 99 | "typedef-whitespace": [ 100 | true, 101 | { 102 | "call-signature": "nospace", 103 | "index-signature": "nospace", 104 | "parameter": "nospace", 105 | "property-declaration": "nospace", 106 | "variable-declaration": "nospace" 107 | } 108 | ], 109 | "unified-signatures": true, 110 | "variable-name": false, 111 | "whitespace": [ 112 | true, 113 | "check-branch", 114 | "check-decl", 115 | "check-operator", 116 | "check-separator", 117 | "check-type" 118 | ], 119 | "no-output-on-prefix": true, 120 | "use-input-property-decorator": true, 121 | "use-output-property-decorator": true, 122 | "use-host-property-decorator": true, 123 | "no-input-rename": true, 124 | "no-output-rename": true, 125 | "use-life-cycle-interface": true, 126 | "use-pipe-transform-interface": true, 127 | "component-class-suffix": true, 128 | "directive-class-suffix": true 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /hw3/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/linux,python,django 2 | 3 | ### Django ### 4 | *.log 5 | *.pot 6 | *.pyc 7 | __pycache__/ 8 | local_settings.py 9 | db.sqlite3 10 | media 11 | 12 | # If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ 13 | # in your Git repository. Update and uncomment the following line accordingly. 14 | # /staticfiles/ 15 | 16 | ### Linux ### 17 | *~ 18 | 19 | # temporary files which can be created if a process still has a handle open of a deleted file 20 | .fuse_hidden* 21 | 22 | # KDE directory preferences 23 | .directory 24 | 25 | # Linux trash folder which might appear on any partition or disk 26 | .Trash-* 27 | 28 | # .nfs files are created when an open file is removed but is still being accessed 29 | .nfs* 30 | 31 | ### Python ### 32 | # Byte-compiled / optimized / DLL files 33 | *.py[cod] 34 | *$py.class 35 | 36 | # C extensions 37 | *.so 38 | 39 | # Distribution / packaging 40 | .Python 41 | env/ 42 | build/ 43 | develop-eggs/ 44 | dist/ 45 | downloads/ 46 | eggs/ 47 | .eggs/ 48 | lib/ 49 | lib64/ 50 | parts/ 51 | sdist/ 52 | var/ 53 | wheels/ 54 | *.egg-info/ 55 | .installed.cfg 56 | *.egg 57 | 58 | # PyInstaller 59 | # Usually these files are written by a python script from a template 60 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 61 | *.manifest 62 | *.spec 63 | 64 | # Installer logs 65 | pip-log.txt 66 | pip-delete-this-directory.txt 67 | 68 | # Unit test / coverage reports 69 | htmlcov/ 70 | .tox/ 71 | .coverage 72 | .coverage.* 73 | .cache 74 | nosetests.xml 75 | coverage.xml 76 | *,cover 77 | .hypothesis/ 78 | 79 | # Translations 80 | *.mo 81 | 82 | # Django stuff: 83 | 84 | # Flask stuff: 85 | instance/ 86 | .webassets-cache 87 | 88 | # Scrapy stuff: 89 | .scrapy 90 | 91 | # Sphinx documentation 92 | docs/_build/ 93 | 94 | # PyBuilder 95 | target/ 96 | 97 | # Jupyter Notebook 98 | .ipynb_checkpoints 99 | 100 | # pyenv 101 | .python-version 102 | 103 | # celery beat schedule file 104 | celerybeat-schedule 105 | 106 | # SageMath parsed files 107 | *.sage.py 108 | 109 | # dotenv 110 | .env 111 | 112 | # virtualenv 113 | .venv 114 | venv/ 115 | ENV/ 116 | 117 | # Spyder project settings 118 | .spyderproject 119 | .spyproject 120 | 121 | # Rope project settings 122 | .ropeproject 123 | 124 | # mkdocs documentation 125 | /site 126 | 127 | # End of https://www.gitignore.io/api/linux,python,django 128 | 129 | .idea 130 | solution 131 | .DS_Store 132 | -------------------------------------------------------------------------------- /hw3/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017-2018 Software Platform Lab 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /hw3/README.md: -------------------------------------------------------------------------------- 1 | # Homework 3 - Angular Testing and Django 2 | 3 | **Due: 11/2 (Fri) 20:59 (This is a hard deadline)** 4 | 5 | ## Angular Testing 6 | 7 | You need to implement unit tests for your Angular project you already submitted in homework 2. 8 | This was a part of homework 2 but postponed due to the course schedule. 9 | Therefore, you **must** not modify your project features (in `*.ts` files except `*.spec.ts`) but just update (or add) the `*.spec.ts` files to make all `*.ts` files under your `src/app` directory should have corresponding `*.spec.ts` files that performs unit tests on your code. 10 | 11 | **All pages/components should have proper unit tests to test its functionalities**, written in Jasmine, run by Karma (as shown in [this link](https://angular.io/guide/testing) and the practice session). 12 | Your tests are expected to cover all of your code, and we will give credits according to your coverage results. 13 | You can see the coverage information of your application as shown [here](https://www.angularonrails.com/add-test-coverage-report-angular-cli-project/). Also, all of your tests must pass. 14 | 15 | ## Django 16 | 17 | In this assignment you will implement a backend service for the blog frontend that you have created in homework 2. 18 | This is an **individual** assignment. 19 | 20 | Through this assignment, you are expected to: 21 | 22 | - Build a RESTful API server with Django (2.1.2) 23 | - Understand how communication between the client and the server occurs 24 | - Test your Django application 25 | 26 | ### Comments on files 27 | 28 | Our `myblog` project consists of a single app, `blog`. 29 | Because we provide the url routing and setting of the project already, you are expected to update the `blog` app mainly. 30 | 31 | ### Features 32 | 33 | As you have seen in homework 2, our blog has three models: User, Article, and Comment. 34 | 35 | - Each user should be able to sign up, sign in and sign out. 36 | - Only those users who are signed in are allowed to read or write articles and comments. 37 | - Users should be able to update or delete articles and comments only which they have created. 38 | 39 | For the user model, you **must** use the [Django default user model](https://docs.djangoproject.com/en/2.1/topics/auth/) and the django authentication system to manage user authentication. 40 | In homework 2, we didn't cover the real user authentication process. 41 | Now with a proper backend, we can manage user sessions and authentication supported by Django. 42 | 43 | For articles, you need to create a model named as `Article` that consists of following fields: 44 | 45 | | Field name | Type | 46 | |------------------------|-----| 47 | | `title` | Char Field | 48 | | `content` | Text Field | 49 | | `author` | Foreign Key | 50 | 51 | The author must be a (foreign) key referring a User. 52 | 53 | For comments, you need to create a model named as `Comment` that consists of following fields: 54 | 55 | | Field name | Type | 56 | |------------------------|-----| 57 | | `article` | Foreign Key | 58 | | `content` | Text Field | 59 | | `author` | Foreign Key | 60 | 61 | The article and author must be a (foreign) key referring an Article and a User. 62 | 63 | To check whether you implemented your model correctly or not, please check the following code works well with your model implementation (in your test code or somewhere else). 64 | 65 | ``` 66 | from .models import Article, Comment 67 | from django.contrib.auth.models import User 68 | 69 | new_user = User.objects.create_user(username='swpp', password='iluvswpp') # Django default user model 70 | new_article = Article(title='I Love SWPP!', content='Believe it or not', author=new_user) 71 | new_article.save() 72 | new_comment = Comment(article=new_article, content='Comment!', author=new_user) 73 | new_comment.save() 74 | ``` 75 | 76 | Detailed specifications of RESTful APIs are as following: 77 | 78 | | API | GET | POST | PUT | DELETE | 79 | |------------------------|-----|------|-----|--------| 80 | | `api/signup` | X | Create new user | X | X | 81 | | `api/signin` | X | Log in | X | X | 82 | | `api/signout` | Log out | X | X | X | 83 | | `api/article` | Get article list | Create new article | X | X | 84 | | `api/article/:article_id` | Get specified article | X | Edit specified article | Delete specified article | 85 | | `api/article/:article_id/comment` | Get comments of specified article | Create comment on specified article | X | X | 86 | | `api/comment/:comment_id` | Get specified comment | X | Edit specified comment | Delete specified comment | 87 | 88 | Note that the APIs are slightly different from that of homework 2. Since we have used mock-backend, APIs were limited in homework 2. 89 | In this assignment, we will implement a more RESTful API. 90 | 91 | POST and PUT requests should contain data using the JSON format in the body of the request. 92 | For each model, the JSON format should look like: 93 | 94 | - User : `{username: string, password: string}` 95 | - Article : `{title: string, content: string}` 96 | - Comment : `{content: string}` 97 | 98 | Also, the user information will be included in the `request` automatically. Check `request.user`. 99 | 100 | For each API you should respond with the appropriate HTTP response code. 101 | The list of response codes you should use is as follows: 102 | 103 | - `200` (Ok) : Request was responded successfully. 104 | - `201` (Created) : Request has created new resources successfully. 105 | - `204` (No Content) : Request was responded successfully but without any content. 106 | - `401` (Unauthorized) : Request requires authentication. This should be returned if you are requesting without signing in. 107 | - `403` (Forbidden) : Request is forbidden. This should be returned if your request tries to modify resources of which you are not the owner. 108 | - `404` (Not Found) : Requested resource is not found. 109 | - `405` (Method not allowed) : Requested URL does not allow the method of the request. 110 | 111 | Please make sure to implement your request methods under the following global specifications: 112 | 113 | - For all non-allowed requests (X marked in the API table), response with `405`. 114 | - For all requests about article and comment without signing in, response with `401` (and any information must not be modified). 115 | - For all requests about non-existing article and comment, response with `404` (and any information must not be modified). 116 | - For all PUT and DELETE requests from non-author, response with `403` (and any information must not be modified). 117 | 118 | Among these global specifications, the prior specification has the higher priority. For example, if someone requests for a non-existing article without signing in, response with `401` instead of `404`. 119 | 120 | Also, please make sure to implement your request methods under the following detailed specifications (in your `views.py`) 121 | 122 | - POST `api/signup` 123 | Create a user with the information given by request JSON body and response with `201` 124 | - POST `api/signin` 125 | Authenticate with the information given by request JSON body. If success, log-in (the authentication info should be changed properly) and response with `204`. If fail, response with `401`. 126 | - GET `api/signout` 127 | If the user is authenticated, log-out (the authentication info should be changed properly) and response with `204`. If not, response with `401`. 128 | - GET `api/article` 129 | Response with a JSON having a list of dictionaries for each article's `title`, `content`, and `author`. The value of the `author` must be the `id` of the author but not her `username`. 130 | - POST `api/article` 131 | Create an article with the information given by request JSON body and response with `201` 132 | - GET `api/article/:article_id` 133 | Response with a JSON having a dictionary for the target article's `title`, `content`, and `author`. The value of the `author` must be the `id` of the author but not her `username`. 134 | - PUT `api/article/:article_id` 135 | Update the target article with the information given by request JSON body and response with `200` 136 | - DELETE `api/article/:article_id` 137 | Delete the target article and response with `200`. When deleting an article, all comments under the target article (but not any comments under other articles, of course) **must** be deleted also. 138 | - GET `api/article/:article_id/comment` 139 | Response with a JSON having a list of dictionaries for each comment's `article`, `content`, and `author`. The value of the `article` and the `author` must be the `id` of the article and the author but not the `title` and her `username`. 140 | - POST `api/article/:article_id/comment` 141 | Create a comment with the information given by request JSON body and response with `201`. 142 | - GET `api/comment/:comment_id` 143 | Response with a JSON having a dictionary for the target comment's `article`, `content`, and `author`. The value of the `article` and the `author` must be the `id` of the article and the author but not the `title` and her `username`. 144 | - PUT `api/comment/:comment_id` 145 | Update the target comment with the information given by request JSON body and response with `200` 146 | - DELETE `api/comment/:comment_id` 147 | Delete the target comment and response with `200`. When deleting a comment, other users, articles and comments **must** not be deleted also. 148 | 149 | ### Testing 150 | 151 | You should also write tests to verify that your blog backend is implemented correctly. 152 | Your tests should reach **100%** of both the statement coverage and the branch coverage. 153 | 154 | You can run your test code with coverage check by: 155 | - Install : `pip install coverage` 156 | - Statement coverage : `coverage run --source='./blog' manage.py test` 157 | - Branch coverage : `coverage run --branch --source='./blog' manage.py test` 158 | 159 | After this, you can check your coverage report by: 160 | - `coverage report` 161 | 162 | 163 | ### Tips 164 | 165 | In Django, it is rather complex to send request other than GET method with RESTful API due to the [CSRF token](https://docs.djangoproject.com/en/2.1/ref/csrf/). 166 | To successfully handle such requests, try the following steps: 167 | 168 | 1. Before sending the request, send GET request to `/api/token`. The response will come with an empty content and will set the cookie `csrftoken` in your browser. 169 | 2. Send the POST request with a header containing `HTTP_X_CSRFTOKEN` as the value of the `csrftoken`. 170 | 171 | For more detail, see `test_csrf` of the `blog/tests.py` file in the skeleton code. 172 | You may change this part if you have a better way of handling the CSRF token, but disabling the protection itself is **NOT** permitted. 173 | 174 | To test your APIs, we recommend using ARC (Advanced REST Client). Check `arc.pdf` for detailed information. 175 | 176 | ## Grading 177 | 178 | This assignment is composed of a total of 85 points (15 points for Angular testing and 70 points for Django). 179 | We will test your Django code under Python 3.6. 180 | 181 | - Angular Testing (15 points) 182 | - User APIs (15 points) 183 | - Article APIs (20 points) 184 | - Comment APIs (20 points) 185 | - Django Testing (15 points) 186 | 187 | Like HW 2, if some basic features are not implemented properly, many other test cases can fail. 188 | For example, if the signing-in process works badly, most of the cases above will fail. 189 | We'll try to give some partial points in this case, but it might not be enough. 190 | 191 | ## Submission 192 | 193 | **Due: 11/2 (Fri) 20:59 (This is a hard deadline)** 194 | 195 | We will check the snapshot of the *master* branch of your Github repository at the deadline and grade it. 196 | Please name your repository as `swpp-hw3-YOUR_USERNAME`, and replace YOUR_USERNAME with you own GitHub username. 197 | Refer to HW1 to create another private repository. (Make sure to push your work on Github on time and add `sanha`, `yuyupopo`, and `skystar-p` as a collaborator in your repository settings.) 198 | Also, make sure to push your work on Github on time. 199 | You won't need to send us an email for submission, but we will pull each repositories at the time specified. 200 | 201 | Please put your angular projects and django projects in the root folder (not inside another `hw3` or `skeleton` folder) appropriately. 202 | Your directory hierarchy should look like this: 203 | ``` 204 | repository_root/ 205 | angular/ 206 | README.md 207 | e2e/ 208 | ... 209 | src/ 210 | app/ 211 | assets/ 212 | environment/ 213 | ... 214 | package.json 215 | ... 216 | django/ 217 | README.md (this file) 218 | blog/ 219 | ... 220 | myblog/ 221 | ... 222 | manage.py 223 | ... 224 | ``` 225 | -------------------------------------------------------------------------------- /hw3/arc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/hw3/arc.pdf -------------------------------------------------------------------------------- /hw3/skeleton/blog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/hw3/skeleton/blog/__init__.py -------------------------------------------------------------------------------- /hw3/skeleton/blog/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /hw3/skeleton/blog/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BlogConfig(AppConfig): 5 | name = 'blog' 6 | -------------------------------------------------------------------------------- /hw3/skeleton/blog/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/hw3/skeleton/blog/migrations/__init__.py -------------------------------------------------------------------------------- /hw3/skeleton/blog/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /hw3/skeleton/blog/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase, Client 2 | import json 3 | 4 | 5 | class BlogTestCase(TestCase): 6 | def test_csrf(self): 7 | # By default, csrf checks are disabled in test client 8 | # To test csrf protection we enforce csrf checks here 9 | client = Client(enforce_csrf_checks=True) 10 | response = client.post('/api/signup', json.dumps({'username': 'chris', 'password': 'chris'}), 11 | content_type='application/json') 12 | self.assertEqual(response.status_code, 403) # Request without csrf token returns 403 response 13 | 14 | response = client.get('/api/token') 15 | csrftoken = response.cookies['csrftoken'].value # Get csrf token from cookie 16 | 17 | response = client.post('/api/signup', json.dumps({'username': 'chris', 'password': 'chris'}), 18 | content_type='application/json', HTTP_X_CSRFTOKEN=csrftoken) 19 | self.assertEqual(response.status_code, 201) # Pass csrf protection 20 | -------------------------------------------------------------------------------- /hw3/skeleton/blog/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from blog import views 3 | 4 | urlpatterns = [ 5 | path('signup', views.signup, name='signup'), 6 | path('token', views.token, name='token'), 7 | ] -------------------------------------------------------------------------------- /hw3/skeleton/blog/views.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponse, HttpResponseNotAllowed 2 | from django.contrib.auth.models import User 3 | from django.views.decorators.csrf import ensure_csrf_cookie 4 | import json 5 | 6 | 7 | def signup(request): 8 | if request.method == 'POST': 9 | req_data = json.loads(request.body.decode()) 10 | username = req_data['username'] 11 | password = req_data['password'] 12 | User.objects.create_user(username=username, password=password) 13 | return HttpResponse(status=201) 14 | else: 15 | return HttpResponseNotAllowed(['POST']) 16 | 17 | 18 | @ensure_csrf_cookie 19 | def token(request): 20 | if request.method == 'GET': 21 | return HttpResponse(status=204) 22 | else: 23 | return HttpResponseNotAllowed(['GET']) 24 | -------------------------------------------------------------------------------- /hw3/skeleton/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == '__main__': 6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myblog.settings') 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /hw3/skeleton/myblog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/hw3/skeleton/myblog/__init__.py -------------------------------------------------------------------------------- /hw3/skeleton/myblog/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for myblog project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.1.2. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.1/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '@fq!6l175f#(m5sgfvwgxnhp3pgo1ts)aa)#k80%r%5n$vp%he' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'blog.apps.BlogConfig', 35 | 'django.contrib.admin', 36 | 'django.contrib.auth', 37 | 'django.contrib.contenttypes', 38 | 'django.contrib.sessions', 39 | 'django.contrib.messages', 40 | 'django.contrib.staticfiles', 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'myblog.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'myblog.wsgi.application' 72 | 73 | 74 | # Database 75 | # https://docs.djangoproject.com/en/2.1/ref/settings/#databases 76 | 77 | DATABASES = { 78 | 'default': { 79 | 'ENGINE': 'django.db.backends.sqlite3', 80 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 81 | } 82 | } 83 | 84 | 85 | # Password validation 86 | # https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators 87 | 88 | AUTH_PASSWORD_VALIDATORS = [ 89 | { 90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 91 | }, 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 100 | }, 101 | ] 102 | 103 | 104 | # Internationalization 105 | # https://docs.djangoproject.com/en/2.1/topics/i18n/ 106 | 107 | LANGUAGE_CODE = 'en-us' 108 | 109 | TIME_ZONE = 'UTC' 110 | 111 | USE_I18N = True 112 | 113 | USE_L10N = True 114 | 115 | USE_TZ = True 116 | 117 | 118 | # Static files (CSS, JavaScript, Images) 119 | # https://docs.djangoproject.com/en/2.1/howto/static-files/ 120 | 121 | STATIC_URL = '/static/' 122 | -------------------------------------------------------------------------------- /hw3/skeleton/myblog/urls.py: -------------------------------------------------------------------------------- 1 | """myblog URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import include, path 18 | 19 | urlpatterns = [ 20 | path('admin/', admin.site.urls), 21 | path('api/', include('blog.urls')), 22 | ] 23 | -------------------------------------------------------------------------------- /hw3/skeleton/myblog/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for myblog project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myblog.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /project/README.md: -------------------------------------------------------------------------------- 1 | ## Project 2 | 3 | The project will follow this process: 4 | 5 | - Project team formation 6 | - [Project proposal](projectproposal.md) 7 | - Project sprint 1 _(Features + Setup)_ 8 | - [Requirements and specification](project-requirements-and-specification.md) 9 | - Project sprint 2 _(Proof-of-Concept)_ 10 | - Revised requirements and specification 11 | - [Design and planning](design-and-planning.md) 12 | - Working code up to project sprint 2 13 | - Project sprint 3 _(Feature Development)_ 14 | - Revised requirements and specification 15 | - Revised design and planning 16 | - Working code up to project sprint 3 17 | - Project sprint 4 _(Exception Handling + Testing)_ 18 | - Revised requirements and specification 19 | - Revised design and planning 20 | - Working code up to project sprint 4 21 | - Project sprint 5 _(Deployment + Optimization)_ 22 | - Revised requirements and specification 23 | - Revised design and planning 24 | - Working code up to project sprint 5 25 | - Project sprint 6 _(Wrap Up!)_ 26 | - Revised requirements and specification 27 | - Revised design and planning 28 | - Working code up to project sprint 6 29 | - [Final demo poster session](postersession.md) & final report 30 | 31 | Note : Every document for each milestones must be written in **English**! 32 | 33 | [Sprint Instructions](sprint-instructions.md) 34 | 35 | ## Project examples 36 | - [2018 Team 1](https://github.com/swsnu/swpp18-team1) 37 | - [2018 Team 4](https://github.com/swsnu/swpp18-team4) 38 | - [2018 Team 11](https://github.com/swsnu/swpp18-team11) 39 | 40 | ## Project Timeline 41 | | | Start | End | TA meeting | 42 | |-|-------|-----|------------| 43 | | Sprint 1 | Sep. 25 (Tue)| Oct. 8 (Mon), 6pm(report due) | TBD | 44 | | Sprint 2 | Oct. 9 (Tue)| Oct. 23 (Tue), 6pm(report due) | TBD | 45 | | Project progress presentation | Oct. 31 practice session (Tentative) | | | 46 | | Sprint 3 | Oct. 23 (Tue)| Nov. 5 (Mon), 6pm(report due) | TBD | 47 | | Sprint 4 | Nov. 6 (Tue)| Nov. 19 (Mon), 6pm(report due) | TBD | 48 | | Sprint 5 | Nov. 20 (Tue)| Dec. 3 (Mon), 6pm(report due) | TBD | 49 | | Sprint 6 | Dec. 4 (Tue)| Dec. 17 (Mon) - no report | TBD | 50 | | Final poster | Dec. 18 (Tue) 10:00 am - 12:00 pm | | | 51 | | Final report | | Dec. 20 (Thur) 8:59pm | | 52 | -------------------------------------------------------------------------------- /project/design-and-planning-examples/Design_and_Planning_example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/project/design-and-planning-examples/Design_and_Planning_example.pdf -------------------------------------------------------------------------------- /project/design-and-planning.md: -------------------------------------------------------------------------------- 1 | ## Design and Planning Document 2 | 3 | Project Name
4 | Design and Planning Document
5 | ??/??/??,
6 | Version major.minor
7 | 8 | **Instructions**
9 | This is a design and planning document template for SWPP. Please fill out this template carefully. 10 | 11 | This will be a living document. For the first sprint you will fill in the document with the design details as you can see them before the first sprint. In subsequent sprints you will expand this document. 12 | 13 | You have to use Github wiki for this document. 14 | 15 | **Submission**
16 | You must send an email to swpp-staff@spl.snu.ac.kr with a PDF version of your document by the deadline. 17 | 18 | You must send the email by the deadline in the class calendar. This is a HARD deadline. 19 | 20 | **Document Revision History**
21 | Your first version of this document is version 1.0. After that minor changes increment the minor version number (e.g., 1.1, 1.2, …) and major changes increment the major version number and set the minor number to zero (e.g., 2.0, 3.0, …). We will follow this convention with other documents as well. 22 | 23 | Rev. 1.0 YYYY-MM-DD - initial version 24 | 25 | **System Architecture**
26 | Here you should describe the **high-level architecture** of your system: the major pieces and how they fit together. Use graphical notations as much as possible in preference to English sentences. For example, you could describe the architecture using UML, if your system lends itself to these descriptions. Try to use standard architectural elements (e.g., pipe-and-filter, client-server, event-based, model-view-controller). Make sure to describe the major interfaces between components, which you will describe in more detail in the "Design details" section below. 27 | 28 | **Design Details**
29 | In this section go those important facets that are not at the level of “architecture,” such as descriptions of critical algorithms, protocols, and key invariants. Also, wherever possible items should be linked back to your specification. Ideally, you can match up everything in the specification with where it is implemented in the design. 30 | 31 | We expect that once this document is completed you will split into subteams to implement the various major components. To be ready for such a split, you need to have a precise idea of how the components are interacting, and how you are going to start implementing them. A complete class-level design might not be always possible so early, but you need to specify at least the API among the major components. Use UML when appropriate. 32 | 33 | If there are messages sent between clients and servers, you should identify **what messages and what data they contain, and in what format, and in what order they should be sent.** 34 | 35 | We expect to see a more refined design for the features to be included in the current sprint, and perhaps a more rough design for the features to be implemented in future sprints. 36 | 37 | If you have considered alternative designs, please describe briefly your reasons for choosing the final design. 38 | 39 | **Implementation Plan**
40 | Break down each user story described in your requirements document into programming tasks. Determine the difficulty of each task, and try to estimate the number of developer-days that the tasks should take. Try to also determine dependencies among tasks. Then, you should list all of the tasks to be done in the current sprint, a preliminary assignment of tasks to people in the group, estimates of the time for each task, dependencies between tasks, and a preliminary division into sprints (e.g., which features are implemented in the first sprint, second sprint, and so on). The plan should be designed to get some prototype system running as quickly as possible and then growing towards to the full project over a sequence of sprints. Please pay extra attention to the dependency relationships between tasks; you will almost certainly run into the situation where one bit isn't done but everything else is waiting for it. In that case, you want to know exactly where resources need to go, and how urgent each bit is (hint: NOT proportional to its size or importance in the whole system). 41 | 42 | Try to identify the major risks for the project in general and the plan in particular. Explain what the risks are and discuss how you plan to mitigate them. 43 | 44 | **Testing Plan**
45 | In this section goes a brief description of how you plan to test the system. Thought should be given to how mostly automatic testing can be carried out, so as to maximize the limited number of human hours you will have for testing your system. The effort you put early on on automated testing will pay off when you have to ensure that you are not breaking existing functionality in future sprints. 46 | Consider the following kinds of testing: 47 | 48 | - **Unit testing**: explain for what modules you plan to write unit tests, and what framework you plan to use.
49 | - **Functional testing**: What APIs you plan to test? How will you test them? What tools you will use? Will you write mocks?
50 | - **Acceptance & integration testing**: how do you plan to test the user interface and scenarios?
51 | 52 | **Registering Issues**
53 | You have to register Github issues regarding tasks for design, implementation, and testing and mark them with milestones. 54 | 55 | **Design and planning document grading guidelines**
56 | These are the grading guidelines that staff will use to evaluate your document. 57 | 58 | | Max points | Design | 59 | |-------------|--------| 60 | | 8 | Are all parts of the document in agreement with the product requirements? | 61 | | 10 | Is the architecture of the system described, with the major components and their interfaces? | 62 | | 10 | Are all the external interfaces to the system specified in detail? | 63 | | 10 | Are the major internal interfaces (e.g., client-server) specified in detail? | 64 | | 8 | Is there sufficient detail in the design to start Iteration 1? | 65 | | 4 | Is there reasonable detail in the design for features in future iterations? | 66 | | | **Planning** | 67 | | 8 | Is the plan for Iteration 1 sufficiently complete to start the implementation ? | 68 | | 4 | Are the subteams identified and has enough thought been given to parallelization of effort and team dependencies? | 69 | | 4 | Is there a discussion of the risks associated with this plan? | 70 | | 4 | Are the testing activities scheduled at the appropriate times? | 71 | | | **Testing** | 72 | | 5 | Does the design take into account testability of the various units, components, and subsystems ? | 73 | | 4 | Is there a discussion of how unit testing will be done? | 74 | | 6 | Is there a discussion of how functional (API) testing will be done automatically? | 75 | | 4 | Is there a discussion of how acceptance/integration testing will be done? | 76 | | | **Clarity** | 77 | | 4 | Is the solution at a fairly consistent and appropriate level of detail? | 78 | | 4 | Is the solution clear enough to be turned over to an independent group for implementation and still be understood? | 79 | | 5 | Is the document making good use of semi-formal notation (UML, diagrams, etc) | 80 | | 4 | Is the document identifying common architectural or design patterns, where appropriate? | 81 | | 4 | Is the document carefully written, without typos and grammatical errors? | 82 | -------------------------------------------------------------------------------- /project/postersession.md: -------------------------------------------------------------------------------- 1 | ## Poster Session 2 | 3 | A check list for the poster. 4 | - Catchy name 5 | - Examples 6 | - LinkedIn: Connect, share ideas, and discover opportunities 7 | - Uber: Moving people 8 | - Facebook: Connect with friends and the world around you on Facebook 9 | - Github: Build software better, together 10 | 11 | - Descriptions (2-4 sentences, max 60 words) 12 | - Use the poster template 13 | - Prepare well for your demo 14 | 15 | -------------------------------------------------------------------------------- /project/project-requirements-and-specification.md: -------------------------------------------------------------------------------- 1 | ## Project Requirements and Specification 2 | 3 | **Project Requirements and Specification**
4 | (Borrowed and Adapted from UCB CS169) 5 | 6 | Your Project Name
7 | Requirements and Specification Document
8 | ??/??/????, version major.minor 9 | 10 | **Instructions**
11 | This is a requirements and specification document template for Software Development Principles and Practices. Please follow these directions for filling out this template. Items in italics are information that you are to fill in, beginning with the project name, date, and version number above. See below for an explanation of version numbers. 12 | 13 | There is no standard for requirements or specifications documents and in fact many organizations blend aspects of requirements, specification, and design in a single document. We will use a simple template for requirements and specification. Inevitably in preparing this document you will discuss design and planning, but limit this document to requirements, a description of how the system should interact with the outside world. 14 | 15 | This will be a living document. For the first sprint you will fill in the overview sections (Abstract, Customer, Competitive Landscape), and a few of the requirements that you plan to implement in the first sprint. In subsequent sprints you will expand the applicable sections. 16 | 17 | You have to use the Github wiki of your private team repo. 18 | 19 | **Submission**
20 | You must send an email to swpp-staff@spl.snu.ac.kr with a PDF version of your document. 21 | You must send the email by the deadline in the class calendar. This is a HARD deadline. 22 | 23 | 24 | **Project Abstract**
25 | A one paragraph summary (about 200 words) of what the software will do. (**Must include in the first version.**) 26 | 27 | **Document Revision History**
28 | Your first version of this document is version 1.0. When you evolve this document for future sprints of your project you will increment the minor version number (e.g., 1.1, 1.2, ...). We do not expect that you will have to increment the major version number in the course of this semester. For every version after the initial version, you should list a short bullet list with the main changes and extensions that you made to the document: 29 | 30 | Rev. 1.0 YYYY-MM-DD - initial version 31 | 32 | **Customer**
33 | A brief description of the customer for this software, both in general (the population who might eventually use such a system) and specifically for this document (the customer(s) who informed this document). (**Must include in the first version**) 34 | 35 | 36 | **Competitive Landscape**
37 | Briefly identify the competitors in this market, and list the main ways in which your project is going to be different. 38 | (**Must include in the first version**) 39 | 40 | **User Stories**
41 | This section will include the specification for your project in the form of user stories. For each user story, you should have at least a Feature and one or more Scenarios, each of which can have one or more Acceptance Tests. Acceptance Tests list one or more acceptance tests with concrete values for the parameters, and concrete assertions that you will make to verify the postconditions. Each user story should also have a field called "Sprint" where you specify in which sprint you implemented or plan to implement this feature. 42 | You should list only the user stories for the previous sprints and those for the current sprint. 43 | 44 | At the end of this section you should maintain a bullet list of user stories that you plan to get to in future sprints, with only minimal detail for each such story. We expect that in future sprints some of these items will be promoted to full fledged user stories. 45 | (**Must include in the first version, and must be expanded for future sprints**) 46 | 47 | **User Interface Requirements**
48 | Describes any customer user interface requirements including graphical user interface requirements. Here you should have sketches or mockups for the main parts of the interface. To save time you may want to use scanned drawings of interface mockups here, instead of Photoshop drawings. 49 | 50 | Just like for the User Stories section, you need to list here only the parts of the user interface that are applicable to the previous sprints and the current one. 51 | (**Must include in the first version, and must be expanded for future sprints**) 52 | 53 | 54 | **Requirements grading guidelines:**
55 | These are the grading guidelines that staff will use to evaluate your document. 56 | 57 | 58 | | Max Points | Content | 59 | |------------|---------| 60 | | 5 | Do the requirements state the customers needs? | 61 | | 5 | Competitive analysis | 62 | | 5 | Do the requirements avoid specifying a design (customer-specified design elements are allowed) ? | 63 | | 5 | Do you believe all parts are possible to implement? | 64 | | 5 | Is the project scope big enough? | 65 | | | **Completeness** | 66 | | 20| Are the user stories written in sufficient detail to allow for design and planning? | 67 | | 5 | Do the user stories have acceptance tests ? | 68 | | 5 | Do the user stories mention error conditions and required behavior ? | 69 | | 5 | Are there sufficient user stories for the first iteration? | 70 | | 5 | Is there a discussion of the stories for future iterations ? | 71 | | 20 | Are the User Interface Requirements given with some detail? Are there some sketches, mockups?| 72 | | | **Clarity** | 73 | | 5 | Is the document carefully written, without typos and grammatical errors? | 74 | | 5 | Is each part of the document in agreement with all other parts? | 75 | | 5 | Are all items clear and not ambiguous? (Minor document readability issues should be handled off-line, not in the review, e.g. spelling, grammar, and organization).| 76 | -------------------------------------------------------------------------------- /project/projectproposal.md: -------------------------------------------------------------------------------- 1 | ## Project proposal guideline 2 | 3 | Write a 2-page project proposal on a web service software system you would like to build this semester. Think ambitiously. Imagine that you create a new start-up. Who knows that you may actually start a new company with the service you build during this course! 4 | 5 | You can propose a new web service that innovates e-commerce, social network service, education, recommendation, multi-player gaming, location-based service, etc. In the proposal, you have to justify why the service is an interesting system to build and what new feature(s) it brings to market. 6 | 7 | In particular, your proposal should include: 8 | - the proposer names (team information) 9 | - a title (it can be changed later) 10 | - your target customers 11 | - what feature the system would add or what problem the system would solve and why the system is important and exciting 12 | - what the system would do 13 | - how you will test and demo the system 14 | 15 | Send your proposal in pdf or doc to swpp-staff at spl.snu.ac.kr via email. 16 | 17 | Please write your proposal in *English*! 18 | 19 | For your reference: [Proposal Examples](proposal-examples) 20 | -------------------------------------------------------------------------------- /project/proposal-examples/Team1 - BusyWrite.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/project/proposal-examples/Team1 - BusyWrite.pdf -------------------------------------------------------------------------------- /project/proposal-examples/Team8 - You&Meet - X.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swsnu/swppfall2018/783b8ecac8c53aac11d711c0ac56d6945f3b6a3d/project/proposal-examples/Team8 - You&Meet - X.pdf -------------------------------------------------------------------------------- /project/sprint-instructions.md: -------------------------------------------------------------------------------- 1 | ## Sprint Instructions 2 | 3 | The main part of the project will be done in several sprints. In each sprint you will have to work on several tasks: 4 | - An update of your specification and design documents (Requirements and Design). In Sprint 1 and Sprint 2 you will have extra time to write the first version of the Design document. 5 | - A completion of a running version of your code with a partial set of features 6 | - Testing support and tests for the implemented features 7 | - A (short) progress report 8 | 9 | 10 | **Revised requirements/spec and design documents**
11 | Update the specification and design documents based on the progress you made so far. 12 | - Update the implementation and testing plans (in the design document) to reflect what you have already accomplished. 13 | - Identify the features you are going to implement in the current sprint. Add user stories (to the requirements document), task breakdowns (design doc), and assignments (design doc). You may need to update tasks that weren't completed in the last sprint. Reassess the task difficulties if necessary. 14 | - Flesh out your list of possible features for future sprints (requirements document). Ideally, you should have a rough outline in place for all sprints. You will change this as we do each sprint, but having a general plan in place will be helpful to everyone involved. 15 | - Identify any changes in the requirements, system architecture and design details. 16 | - Ensure the design document is current for the set of features you've implemented to date and will implement in the next sprint. 17 | - Discuss design decisions that affect testing and describe any test interfaces built into the system (in the testing plan section). 18 | 19 | You must mark clearly the parts of the document that were changed. Use the Changes section at the start of the document and use a different font color for the changed parts. 20 | 21 | 22 | **Sprint Progress Report**
23 | Write a short (1~2 pages) summary for sprint and submit it along with the revised documents. 24 | 25 | - What were the main difficulties so far? You should consider both technical and organization issues. 26 | - Were there any features you did not implement as planned, and why? Are you pushing some features to later sprints, and if so, why? 27 | - What tests did you prepare for this sprint, and what are they covering? Did the tests you wrote deviate from your plan? What features are you not testing yet? Did you use any test frameworks? 28 | - You must include in your progress report a test coverage report. The coverage metric must be over 70%. If it's below 70%, you will lose 10% of the overall score of that sprint. This number may change each sprint. 29 | You must specify what tool did you use, and you must include one or more screenshots showing: 30 | - The overall coverage metric 31 | - The list of classes with lowest coverage. Explain why is the coverage low, and what (if anything) you plan to do about it 32 | - Contribution of team members 33 | - Tag a branch or revision in your repository to identify the code you want to submit for sprintN (replace N with 1, 2, ...). The date and time of this revision should be before the deadline. This branch should include a README file with instructions on how to run the application and tests. 34 | 35 | **Submission**
36 | Each team must send an email to swpp-staff@spl.snu.ac.kr by the deadline. The subject line of the email message must start with the word “[SWPP] sprintN” (replace N with 1, 2, ...) followed by your project's name. The email should contain: 37 | Pointers to the (previously submitted) requirements document and design document. 38 | The sprint summary progress report, as described above. 39 | Instructions for your TA to be able to check out a tagged version of the code that constitutes your sprint release. 40 | A url and instructions for using the app in the current stage. 41 | 42 | Additionally, in the project progress presentation you will have to demonstrate a running version of your sprint release. 43 | --------------------------------------------------------------------------------