9 | );
10 | }
11 |
12 | export default App;
13 |
--------------------------------------------------------------------------------
/hw2/skeleton/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | ReactDOM.unmountComponentAtNode(div);
9 | });
10 |
--------------------------------------------------------------------------------
/hw2/skeleton/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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.2/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 |
--------------------------------------------------------------------------------
/hw2/skeleton/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/hw2/skeleton/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/hw2/skeleton/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 40vmin;
8 | pointer-events: none;
9 | }
10 |
11 | .App-header {
12 | background-color: #282c34;
13 | min-height: 100vh;
14 | display: flex;
15 | flex-direction: column;
16 | align-items: center;
17 | justify-content: center;
18 | font-size: calc(10px + 2vmin);
19 | color: white;
20 | }
21 |
22 | .App-link {
23 | color: #61dafb;
24 | }
25 |
26 | @keyframes App-logo-spin {
27 | from {
28 | transform: rotate(0deg);
29 | }
30 | to {
31 | transform: rotate(360deg);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/hw3/skeleton/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Django's command-line utility for administrative tasks."""
3 | import os
4 | import sys
5 |
6 |
7 | def main():
8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myblog.settings')
9 | try:
10 | from django.core.management import execute_from_command_line
11 | except ImportError as exc:
12 | raise ImportError(
13 | "Couldn't import Django. Are you sure it's installed and "
14 | "available on your PYTHONPATH environment variable? Did you "
15 | "forget to activate a virtual environment?"
16 | ) from exc
17 | execute_from_command_line(sys.argv)
18 |
19 |
20 | if __name__ == '__main__':
21 | main()
22 |
--------------------------------------------------------------------------------
/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, 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'])
--------------------------------------------------------------------------------
/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.2/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/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/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017-2019 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 |
--------------------------------------------------------------------------------
/hw2/skeleton/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "skeleton",
3 | "version": "0.1.0",
4 | "private": true,
5 | "proxy": "http://localhost:8000",
6 | "dependencies": {
7 | "enzyme": "^3.10.0",
8 | "enzyme-adapter-react-16": "^1.14.0",
9 | "json-server": "^0.15.1",
10 | "react": "^16.9.0",
11 | "react-dom": "^16.9.0",
12 | "react-scripts": "3.1.1",
13 | "react-test-renderer": "^16.9.0"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test",
19 | "eject": "react-scripts eject",
20 | "backend": "cp api/db.json api/_db.json && json-server --watch api/_db.json --routes api/routes.json --port 8000"
21 | },
22 | "eslintConfig": {
23 | "extends": "react-app"
24 | },
25 | "browserslist": {
26 | "production": [
27 | ">0.2%",
28 | "not dead",
29 | "not op_mini all"
30 | ],
31 | "development": [
32 | "last 1 chrome version",
33 | "last 1 firefox version",
34 | "last 1 safari version"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/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 (at least one of the features must make use of machine learning)
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 |
--------------------------------------------------------------------------------
/hw1/javascript/form.js:
--------------------------------------------------------------------------------
1 | class Form {
2 | constructor(
3 | email,
4 | password,
5 | password_confirmation,
6 | phone_number,
7 | fname,
8 | lname,
9 | age,
10 | birth_month,
11 | birth_day,
12 | birth_year) {}
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 = document.forms["form"]["email"].value;
21 | // TODO: Fill in the rest of the function. Use the Form class defined above
22 |
23 | var 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);
--------------------------------------------------------------------------------
/hw1/javascript/form.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SWPP HW-1: Form checker
6 |
7 |
8 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/hw2/skeleton/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | ### Node ###
4 | # Logs
5 | logs
6 | *.log
7 | npm-debug.log*
8 | yarn-debug.log*
9 | yarn-error.log*
10 |
11 | # Runtime data
12 | pids
13 | *.pid
14 | *.seed
15 | *.pid.lock
16 |
17 | # Directory for instrumented libs generated by jscoverage/JSCover
18 | lib-cov
19 |
20 | # Coverage directory used by tools like istanbul
21 | coverage
22 |
23 | # nyc test coverage
24 | .nyc_output
25 |
26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
27 | .grunt
28 |
29 | # Bower dependency directory (https://bower.io/)
30 | bower_components
31 |
32 | # node-waf configuration
33 | .lock-wscript
34 |
35 | # Compiled binary addons (http://nodejs.org/api/addons.html)
36 | build/Release
37 |
38 | # Dependency directories
39 | node_modules/
40 | jspm_packages/
41 |
42 | # Typescript v1 declaration files
43 | typings/
44 |
45 | # Optional npm cache directory
46 | .npm
47 |
48 | # Optional eslint cache
49 | .eslintcache
50 |
51 | # Optional REPL history
52 | .node_repl_history
53 |
54 | # Output of 'npm pack'
55 | *.tgz
56 |
57 | # Yarn Integrity file
58 | .yarn-integrity
59 |
60 | # dotenv environment variables file
61 | .env
62 |
63 | # dependencies
64 | /node_modules
65 | /.pnp
66 | .pnp.js
67 |
68 | # testing
69 | /coverage
70 |
71 | # production
72 | /build
73 |
74 | # misc
75 | _db.json
76 | .vscode
77 | .idea
78 | .DS_Store
79 | .env.local
80 | .env.development.local
81 | .env.test.local
82 | .env.production.local
83 |
84 | npm-debug.log*
85 | yarn-debug.log*
86 | yarn-error.log*
87 |
--------------------------------------------------------------------------------
/hw2/skeleton/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/project/README.md:
--------------------------------------------------------------------------------
1 | The project will follow this process:
2 |
3 | - Project team formation
4 | - [Project proposal](projectproposal.md)
5 | - Project sprint 1 _(Features + Setup)_
6 | - [Requirements and specification](project-requirements-and-specification.md)
7 | - Project sprint 2 _(Proof-of-Concept)_
8 | - Revised requirements and specification
9 | - [Design and planning](design-and-planning.md)
10 | - Working code up to project sprint 2
11 | - Project sprint 3 _(Feature Development)_
12 | - Revised requirements and specification
13 | - Revised design and planning
14 | - Working code up to project sprint 3
15 | - Project sprint 4 _(Exception Handling + Testing)_
16 | - Revised requirements and specification
17 | - Revised design and planning
18 | - Working code up to project sprint 4
19 | - Project sprint 5 _(Deployment + Optimization)_
20 | - Revised requirements and specification
21 | - Revised design and planning
22 | - Working code up to project sprint 5
23 | - Project sprint 6 _(Wrap Up!)_
24 | - Revised requirements and specification
25 | - Revised design and planning
26 | - Working code up to project sprint 6
27 | - [Final demo poster session](postersession.md) & final report
28 |
29 | Note : Every document for each milestones must be written in **English**!
30 |
31 | [Sprint Instructions](sprint-instructions.md)
32 |
33 | ## Resources
34 | [Code review developer guide](https://google.github.io/eng-practices/review/)
35 |
36 | ## Project Timeline
37 | | | Start | End | TA meeting |
38 | |-|-------|-----|------------|
39 | | Sprint 1 | Sep. 23 (Mon)| Oct. 5 (Sat), 6pm(report due) | TH/F |
40 | | Sprint 2 | Oct. 7 (Mon)| Oct. 19 (Sat), 6pm(report due) | TH/F |
41 | | Sprint 3 | Oct. 21 (Mon)| Nov. 2 (Sat), 6pm(report due) | TH/F |
42 | | Project progress presentation | Nov. 6, Nov. 7 | | |
43 | | Sprint 4 | Nov. 4 (Mon)| Nov. 16 (Sat), 6pm(report due) | TH/F|
44 | | Sprint 5 | Nov. 18 (Mon)| Nov. 30 (Sat), 6pm(report due) | TH/F |
45 | | Sprint 6 | Dec. 2 (Mon)| Dec. 14 (Sat), 6pm report | TH/F |
46 | | Final poster | Dec. 16 (Mon) 5pm - 9pm | | |
47 | | Final report | | Dec. 18 (Wed) 6pm | |
48 |
--------------------------------------------------------------------------------
/hw2/skeleton/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/hw2/skeleton/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
2 |
3 | ## Available Scripts
4 |
5 | In the project directory, you can run:
6 |
7 | ### `npm start`
8 |
9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
11 |
12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console.
14 |
15 | ### `npm test`
16 |
17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
19 |
20 | ### `npm run build`
21 |
22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance.
24 |
25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed!
27 |
28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
29 |
30 | ### `npm run eject`
31 |
32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
33 |
34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
35 |
36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
37 |
38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
39 |
40 | ## Learn More
41 |
42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
43 |
44 | To learn React, check out the [React documentation](https://reactjs.org/).
45 |
46 | ### Code Splitting
47 |
48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
49 |
50 | ### Analyzing the Bundle Size
51 |
52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
53 |
54 | ### Making a Progressive Web App
55 |
56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
57 |
58 | ### Advanced Configuration
59 |
60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
61 |
62 | ### Deployment
63 |
64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
65 |
66 | ### `npm run build` fails to minify
67 |
68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
69 |
--------------------------------------------------------------------------------
/hw3/skeleton/myblog/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for myblog project.
3 |
4 | Generated by 'django-admin startproject' using Django 2.2.6.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/2.2/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/2.2/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.2/howto/deployment/checklist/
21 |
22 | # SECURITY WARNING: keep the secret key used in production secret!
23 | SECRET_KEY = '$6ned!9xc1e7a^e1pgd0%taxdbf9ua=f_gs2gs$8#_i56ry^u%'
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.2/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.2/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.2/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.2/howto/static-files/
120 |
121 | STATIC_URL = '/static/'
122 |
--------------------------------------------------------------------------------
/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 sys
13 | import re
14 | import os
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 |
1
Michael
Jessica
31 |
2
Christopher
Ashley
32 |
3
Matthew
Brittany
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/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea
3 | .vscode
4 |
5 | ### Node ###
6 | # Logs
7 | logs
8 | *.log
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 |
13 | # Runtime data
14 | pids
15 | *.pid
16 | *.seed
17 | *.pid.lock
18 |
19 | # Directory for instrumented libs generated by jscoverage/JSCover
20 | lib-cov
21 |
22 | # Coverage directory used by tools like istanbul
23 | coverage
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (http://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # Typescript v1 declaration files
45 | typings/
46 |
47 | # Optional npm cache directory
48 | .npm
49 |
50 | # Optional eslint cache
51 | .eslintcache
52 |
53 | # Optional REPL history
54 | .node_repl_history
55 |
56 | # Output of 'npm pack'
57 | *.tgz
58 |
59 | # Yarn Integrity file
60 | .yarn-integrity
61 |
62 | # dotenv environment variables file
63 | .env
64 |
65 |
66 | ### Python ###
67 | # Byte-compiled / optimized / DLL files
68 | __pycache__/
69 | *.py[cod]
70 | *$py.class
71 |
72 | # C extensions
73 | *.so
74 |
75 | # Distribution / packaging
76 | .Python
77 | build/
78 | develop-eggs/
79 | dist/
80 | downloads/
81 | eggs/
82 | .eggs/
83 | lib/
84 | lib64/
85 | parts/
86 | sdist/
87 | var/
88 | wheels/
89 | *.egg-info/
90 | .installed.cfg
91 | *.egg
92 |
93 | # PyInstaller
94 | # Usually these files are written by a python script from a template
95 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
96 | *.manifest
97 | *.spec
98 |
99 | # Installer logs
100 | pip-log.txt
101 | pip-delete-this-directory.txt
102 |
103 | # Unit test / coverage reports
104 | htmlcov/
105 | .tox/
106 | .coverage
107 | .coverage.*
108 | .cache
109 | nosetests.xml
110 | coverage.xml
111 | *.cover
112 | .hypothesis/
113 |
114 | # Translations
115 | *.mo
116 | *.pot
117 |
118 | # Django stuff:
119 | *.log
120 | local_settings.py
121 |
122 | # Flask stuff:
123 | instance/
124 | .webassets-cache
125 |
126 | # Scrapy stuff:
127 | .scrapy
128 |
129 | # Sphinx documentation
130 | docs/_build/
131 |
132 | # PyBuilder
133 | target/
134 |
135 | # Jupyter Notebook
136 | .ipynb_checkpoints
137 |
138 | # pyenv
139 | .python-version
140 |
141 | # celery beat schedule file
142 | celerybeat-schedule
143 |
144 | # SageMath parsed files
145 | *.sage.py
146 |
147 | # Environments
148 | .env
149 | .venv
150 | env/
151 | venv/
152 | ENV/
153 |
154 | # Spyder project settings
155 | .spyderproject
156 | .spyproject
157 |
158 | # Rope project settings
159 | .ropeproject
160 |
161 | # mkdocs documentation
162 | /site
163 |
164 | # mypy
165 | .mypy_cache/
166 |
167 |
168 | ### Linux ###
169 | *~
170 |
171 | # temporary files which can be created if a process still has a handle open of a deleted file
172 | .fuse_hidden*
173 |
174 | # KDE directory preferences
175 | .directory
176 |
177 | # Linux trash folder which might appear on any partition or disk
178 | .Trash-*
179 |
180 | # .nfs files are created when an open file is removed but is still being accessed
181 | .nfs*
182 |
183 | ### macOS ###
184 | # General
185 | *.DS_Store
186 | .AppleDouble
187 | .LSOverride
188 |
189 | # Icon must end with two
190 | Icon
191 |
192 |
193 | # Thumbnails
194 | ._*
195 |
196 | # Files that might appear in the root of a volume
197 | .DocumentRevisions-V100
198 | .fseventsd
199 | .Spotlight-V100
200 | .TemporaryItems
201 | .Trashes
202 | .VolumeIcon.icns
203 | .com.apple.timemachine.donotpresent
204 |
205 | # Directories potentially created on remote AFP share
206 | .AppleDB
207 | .AppleDesktop
208 | Network Trash Folder
209 | Temporary Items
210 | .apdisk
211 |
--------------------------------------------------------------------------------
/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 80%. If it's below 80%, 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 |
--------------------------------------------------------------------------------
/hw2/skeleton/src/serviceWorker.js:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.1/8 is considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | export function register(config) {
24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
25 | // The URL constructor is available in all browsers that support SW.
26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
27 | if (publicUrl.origin !== window.location.origin) {
28 | // Our service worker won't work if PUBLIC_URL is on a different origin
29 | // from what our page is served on. This might happen if a CDN is used to
30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
31 | return;
32 | }
33 |
34 | window.addEventListener('load', () => {
35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
36 |
37 | if (isLocalhost) {
38 | // This is running on localhost. Let's check if a service worker still exists or not.
39 | checkValidServiceWorker(swUrl, config);
40 |
41 | // Add some additional logging to localhost, pointing developers to the
42 | // service worker/PWA documentation.
43 | navigator.serviceWorker.ready.then(() => {
44 | console.log(
45 | 'This web app is being served cache-first by a service ' +
46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
47 | );
48 | });
49 | } else {
50 | // Is not localhost. Just register service worker
51 | registerValidSW(swUrl, config);
52 | }
53 | });
54 | }
55 | }
56 |
57 | function registerValidSW(swUrl, config) {
58 | navigator.serviceWorker
59 | .register(swUrl)
60 | .then(registration => {
61 | registration.onupdatefound = () => {
62 | const installingWorker = registration.installing;
63 | if (installingWorker == null) {
64 | return;
65 | }
66 | installingWorker.onstatechange = () => {
67 | if (installingWorker.state === 'installed') {
68 | if (navigator.serviceWorker.controller) {
69 | // At this point, the updated precached content has been fetched,
70 | // but the previous service worker will still serve the older
71 | // content until all client tabs are closed.
72 | console.log(
73 | 'New content is available and will be used when all ' +
74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
75 | );
76 |
77 | // Execute callback
78 | if (config && config.onUpdate) {
79 | config.onUpdate(registration);
80 | }
81 | } else {
82 | // At this point, everything has been precached.
83 | // It's the perfect time to display a
84 | // "Content is cached for offline use." message.
85 | console.log('Content is cached for offline use.');
86 |
87 | // Execute callback
88 | if (config && config.onSuccess) {
89 | config.onSuccess(registration);
90 | }
91 | }
92 | }
93 | };
94 | };
95 | })
96 | .catch(error => {
97 | console.error('Error during service worker registration:', error);
98 | });
99 | }
100 |
101 | function checkValidServiceWorker(swUrl, config) {
102 | // Check if the service worker can be found. If it can't reload the page.
103 | fetch(swUrl)
104 | .then(response => {
105 | // Ensure service worker exists, and that we really are getting a JS file.
106 | const contentType = response.headers.get('content-type');
107 | if (
108 | response.status === 404 ||
109 | (contentType != null && contentType.indexOf('javascript') === -1)
110 | ) {
111 | // No service worker found. Probably a different app. Reload the page.
112 | navigator.serviceWorker.ready.then(registration => {
113 | registration.unregister().then(() => {
114 | window.location.reload();
115 | });
116 | });
117 | } else {
118 | // Service worker found. Proceed as normal.
119 | registerValidSW(swUrl, config);
120 | }
121 | })
122 | .catch(() => {
123 | console.log(
124 | 'No internet connection found. App is running in offline mode.'
125 | );
126 | });
127 | }
128 |
129 | export function unregister() {
130 | if ('serviceWorker' in navigator) {
131 | navigator.serviceWorker.ready.then(registration => {
132 | registration.unregister();
133 | });
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # M1522.000100 Principles and Practices of Software Development
2 |
3 | ## Announcements
4 | - Team formation due 9/10 (Tue) 6pm
5 | - HW1 out; due 9/15 (Sun) 6pm
6 | - Sep.04: Skeleton code of HW1 python updated (to import os package)
7 | - HW2 out; due 10/8 (Tue) 6pm
8 | - Sep.18 (16:05): Minor modification of HW2's backend
9 | - Sep.21 (23:15): Clarification of `article/:id/edit` spec, modification of api `put` description ([diff](https://github.com/swsnu/swppfall2019/commit/07dae919eba6b72155c64a9aa67fcacdcf7dfd1f))
10 | - Sep.23 (09:38): Deadline of hw2 changed (10/4 for feature implementation, 10/11 for testing)
11 |
12 |
13 | ## Assignments
14 |
15 | - Sep. 02 : [homework 1](hw1) is out
16 | - **Due : 9/15 (Sun) 18:00 (hard deadline)**
17 | - This is an individual assignment
18 |
19 | - Sep. 17 : [homework 2](hw2) is out
20 | - **Due : 10/4 (Fri) 18:00 (feature), 10/11 (Fri) 18:00 (unittest) (hard deadline)**
21 | - This is an individual assignment
22 |
23 | - Oct. 07: [homework 3](hw3) is out
24 | - **Due : 10/27 (Sun) 18:00 (hard deadline)**
25 | - This is an individual assignment
26 |
27 | ## [Project Guideline](project)
28 |
29 | ## Schedule (TBD)
30 | | Week | Lecture | Practice Session | Homework / Project / Exam |
31 | |-------|---------|------------------|--------------------|
32 | |9/2,4 | Course overview; project examples ; Project examples | Python, Javascript Basics Review | HW1 out |
33 | |9/9,11| What softwares do, requirements and challenges to make them good, safe, and reliable; How to collaborate as a team and the methods and tools for it | Choosuk (No practice session) | Team formation due 9/10 (Tue) 6pm;
34 | |9/16,18 | Good coding habits. Comments and code conventions | React Tutorial | Project proposal due 9/17 (Tue) 6pm, HW 1 due 9/15 6pm ||
35 | |9/23,25 | Complexity problem and software structures | Redux Tutorial | Project sprint 1 begin (bi-weekly meetings with TAs at the end of sprint) |
36 | |9/30,10/2 | Complexity problem and software structures | React + Redux Testing | |
37 | |10/7,9 | Testing and throwing exceptions, Requirements and specification | CI, Project Setup, Django Intro | HW 2 due 10/11 6pm, Project sprint 2 begin |
38 | |10/14,16 | Software development processes, Design patterns I | Django, React + Django Setup | |
39 | |10/21,23 | Software structure and modeling | Django Testing | Project sprint 3 begin |
40 | |10/28,30 | Code refactoring | Mid-project check | HW 3 due 10/27 6pm |
41 | |11/4,6 | Design patterns 2 | DB + Backend, Writing Good Code | Project sprint 4 begin |
42 | |11/11,13 | Design patterns 3 | Design Pattern, Code Refactoring | |
43 | |11/18,20 | Operation | Code Review | Project sprint 5 begin |
44 | |11/25,27 | Operation (load testing, security) | Deployment + Optimization | Coding exams (Minimum 3 hours) |
45 | |12/2,4 | Code optimization |Deployment + Optimization | Project sprint 6 begin |
46 | |12/9,11 | Advanced topics | | |
47 | |12/15 | Project demo video submission due (6pm) | | |
48 | |12/16 | Project poster session | | Project final report (due 12/18 6pm) |
49 |
50 | ## Office hours
51 | **Professor** :
52 | - Office: Bldg. 302, Rm. 322
53 | - MonWed 4PM-5PM, by appointment
54 |
55 | **TAs** :
56 |
57 | Taebum Kim
58 | - Email: k.taebum@snu.ac.kr
59 | - Office: Bldg. 302, Rm. 420
60 | - Office hour: Wednesday 16:00~17:00
61 |
62 | Kyunggeun Lee
63 | - Email: gurumo0917@gmail.com
64 | - Office: Bldg. 302, Rm. 420
65 | - Office hour: Thursday 17:00~18:00
66 |
67 | Haeyoon Cho
68 | - Email: chohy0555@gmail.com
69 | - Office: Bldg. 302, Rm. 420
70 |
71 | (Please send TAs an email ahead of time, we can set up a specific time and place)
72 |
73 | ## Project Teams
74 | 1. [Matchmaker: Do activities with whoever you want - Smart match making service](https://github.com/swsnu/swpp2019-team1)
75 | 2. [CosMOS : your cosmetics personal shopper](https://github.com/swsnu/swpp2019-team2)
76 | 3. [PapersFeed: Browse and Organize papers, Share and Expand your ideas](https://github.com/swsnu/swpp2019-team3)
77 | 4. [ASSA: Auto Scheduling & Sharing App](https://github.com/swsnu/swpp2019-team4)
78 | 5. [WearHouse: Your very own fashion Warehouse](https://github.com/swsnu/swpp2019-team5)
79 | 6. [Triplannet: Powerful travel planner that helps you to share and organize your travel plans easily](https://github.com/swsnu/swpp2019-team6)
80 | 7. [PillBox : Keep Your Pills Managed. Service that notifies users automatically when to take pills using OCR technology, so that users never miss their pills](https://github.com/swsnu/swpp2019-team7)
81 | 8. [SNUVOICE: Collects SNU Students' Voice](https://github.com/swsnu/swpp2019-team8)
82 | 9. [Fever Time: Let yourself focus. Take record of your concentrated Time](https://github.com/swsnu/swpp2019-team9)
83 | 10. [FoodBook(Food Cabinet): User-experience based review and recommendation service](https://github.com/swsnu/swpp2019-team10)
84 | 11. [surBing: Provides integrated services for survey, response, and result sharing](https://github.com/swsnu/swpp2019-team11)
85 | 12. [MeetingOverFlow: A powerful service that allows you to write and manage your meeting notes efficiently and helps you visualize the flow of your meeting](https://github.com/swsnu/swpp2019-team12)
86 | 13. [Club For You: Create and Join clubs in SNU](https://github.com/swsnu/swpp2019-team13)
87 | 14. [Booksbridge: SNS with your book-reading experience](https://github.com/swsnu/swpp2019-team14)
88 | 15. [OGA: What You See Is What I Need. A location-based Q&A Service](https://github.com/swsnu/swpp2019-team15)
89 | 16. [Ya-Ta!: Taxi sharing for SNU students](https://github.com/swsnu/swpp2019-team16)
90 | 17. [Tu(to)ring Machine: Automate your match, for both tutor and tutee](https://github.com/swsnu/swpp2019-team17)
91 | 18. [S.DA (Sentiment Diary Assistant): Diary Service - Write Easily, Keep Wisely, Share Widely](https://github.com/swsnu/swpp2019-team18)
92 | 19. [SNUBot: Chatbot related to SNU](https://github.com/swsnu/swpp2019-team19)
93 | 20. [Pay me Back!: Manage Dutch Pay, by taking care of complicated accounting and using automatic notification](https://github.com/swsnu/swpp2019-team20)
94 | 21. [Adit - All new advertising platform](https://github.com/swsnu/swpp2019-team21)
95 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/hw2/skeleton/api/db.json:
--------------------------------------------------------------------------------
1 | {
2 | "articles": [
3 | {
4 | "id": 0,
5 | "author_id": 1,
6 | "title": "10 React JS Articles Every Web Developer Should Read",
7 | "content": "Hello Guys, React or React JS is a JavaScript front-end library from Facebook which lets you create HTML based GUI. It makes the task easier by providing a component-based architecture which was only available to languages like Java and C# before."
8 | },
9 | {
10 | "id": 11,
11 | "author_id": 2,
12 | "title": "React: A JavaScript library for building user interfaces",
13 | "content": "React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes."
14 | },
15 | {
16 | "id": 12,
17 | "author_id": 1,
18 | "title": "Building the New facebook.com with React, GraphQL and Relay",
19 | "content": "Open source projects like React, GraphQL and Relay are powering more and more Facebook services. In this session, we'll discuss how we use the latest features of these technologies, like React Suspense, to help deliver a high quality, modern web experience at Facebook."
20 | },
21 | {
22 | "id": 13,
23 | "author_id": 1,
24 | "title": "React State with Hooks: useReducer, useState, useContext",
25 | "content": "If you haven't used state management excessively in React Function Components, this tutorial may help you to get a better understanding of how React Hooks -- such as useState, useReducer, and useContext -- can be used in combination for impressive state management in React applications. In this tutorial, we will almost reach the point where these hooks mimic sophisticated state management libraries like Redux for globally managed state. Let's dive into the application which we will implement together step by step."
26 | },
27 | {
28 | "id": 14,
29 | "author_id": 3,
30 | "title": "From Redux to Hooks: A Case Study",
31 | "content": "Having a single store in Redux comes with benefits, but at the same time you end up putting everything into global namespace. Most applications profit from this, you can even create nested reducers and use naming conventions for actions. But if your global state is small and you know for sure that specific slices of state will only be used by specific areas of your application, making them global makes you feel.. uneasy."
32 | },
33 | {
34 | "id": 15,
35 | "author_id": 2,
36 | "title": "Application State Management with React",
37 | "content": "One of the reasons redux was so successful was the fact that react-redux solved the prop drilling problem. The fact that you could share data across different parts of your tree by simply passing your component into some magical connect function was wonderful. Its use of reducers/action creators/etc. is great too, but I'm convinced that the ubiquity of redux is because it solved the prop drilling pain point for developers."
38 | },
39 | {
40 | "id": 16,
41 | "author_id": 2,
42 | "title": "What I wish I knew when I started to work with React.js",
43 | "content": "After its initial release on May 29, 2013, React.js has taken over the internet. It’s not a secret that myself and many other developers owe their success to this amazing framework."
44 | },
45 | {
46 | "id": 17,
47 | "author_id": 2,
48 | "title": "React’s Five Fingers of Death. Master these five concepts, then master React.",
49 | "content": "A few years ago, my friend Sean started telling me how this brand new front-end library called React was going to take over the web. At first I dismissed it as just another framework fad. But then I started hearing about React more and more, to the point where I felt like ignoring it just wasn’t an option anymore."
50 | },
51 | {
52 | "id": 18,
53 | "author_id": 3,
54 | "title": "Semantic UI: User Interface is the language of the web",
55 | "content": "Semantic 2.4 brings a new components for handling content loading ui placeholder, as well as a new type of segment used to reserve space for content: ui placeholder segment."
56 | },
57 | {
58 | "id": 19,
59 | "author_id": 3,
60 | "title": "Bootstrap: Build responsive, mobile-first projects on the web with the world’s most popular front-end component library",
61 | "content": "Bootstrap is an open source toolkit for developing with HTML, CSS, and JS. Quickly prototype your ideas or build your entire app with our Sass variables and mixins, responsive grid system, extensive prebuilt components, and powerful plugins built on jQuery."
62 | },
63 | {
64 | "id": 20,
65 | "author_id": 3,
66 | "title": "ReactJS Testing",
67 | "content": "Jest is a delightful JavaScript Testing Framework with a focus on simplicity."
68 | }
69 | ],
70 | "comments": [
71 | {
72 | "id": 1,
73 | "article_id": 0,
74 | "author_id": 2,
75 | "content": "What do you mean wow?"
76 | },
77 | {
78 | "id": 2,
79 | "article_id": 0,
80 | "author_id": 3,
81 | "content": "I was surprised"
82 | },
83 | {
84 | "id": 4,
85 | "article_id": 11,
86 | "author_id": 3,
87 | "content": "I agree with you"
88 | },
89 | {
90 | "id": 5,
91 | "article_id": 12,
92 | "author_id": 3,
93 | "content": "Haha this is funny"
94 | },
95 | {
96 | "id": 6,
97 | "article_id": 12,
98 | "author_id": 2,
99 | "content": "Yes, it is hilarious"
100 | },
101 | {
102 | "id": 7,
103 | "article_id": 13,
104 | "author_id": 1,
105 | "content": "I am sad"
106 | },
107 | {
108 | "id": 8,
109 | "article_id": 13,
110 | "author_id": 2,
111 | "content": "I do not want to see you sad"
112 | },
113 | {
114 | "id": 9,
115 | "article_id": 14,
116 | "author_id": 3,
117 | "content": "I do not want to work"
118 | },
119 | {
120 | "id": 10,
121 | "article_id": 15,
122 | "author_id": 3,
123 | "content": "What time is it?"
124 | },
125 | {
126 | "id": 11,
127 | "article_id": 15,
128 | "author_id": 2,
129 | "content": "It is 5 in the morning"
130 | },
131 | {
132 | "id": 12,
133 | "article_id": 16,
134 | "author_id": 1,
135 | "content": "I like it"
136 | },
137 | {
138 | "id": 13,
139 | "article_id": 17,
140 | "author_id": 1,
141 | "content": "I don't think so"
142 | },
143 | {
144 | "id": 14,
145 | "article_id": 17,
146 | "author_id": 2,
147 | "content": "Me neither"
148 | },
149 | {
150 | "id": 15,
151 | "article_id": 18,
152 | "author_id": 2,
153 | "content": "I am so stressed out"
154 | },
155 | {
156 | "id": 16,
157 | "article_id": 18,
158 | "author_id": 3,
159 | "content": "Stress is bad"
160 | },
161 | {
162 | "id": 17,
163 | "article_id": 18,
164 | "author_id": 2,
165 | "content": "Yeah, I should try to feel better"
166 | },
167 | {
168 | "id": 18,
169 | "article_id": 19,
170 | "author_id": 1,
171 | "content": "My dog is cute"
172 | },
173 | {
174 | "id": 19,
175 | "article_id": 19,
176 | "author_id": 2,
177 | "content": "I think so as well"
178 | },
179 | {
180 | "id": 20,
181 | "article_id": 20,
182 | "author_id": 3,
183 | "content": "Tornado has hit our town"
184 | },
185 | {
186 | "id": 21,
187 | "article_id": 20,
188 | "author_id": 1,
189 | "content": "Oh, what a misery"
190 | },
191 | {
192 | "author_id": 1,
193 | "article_id": 0,
194 | "content": "Wow!",
195 | "id": 22
196 | }
197 | ],
198 | "user": [
199 | {
200 | "id": 1,
201 | "email": "swpp@snu.ac.kr",
202 | "password": "iluvswpp",
203 | "name": "Software Lover",
204 | "logged_in": false
205 | },
206 | {
207 | "id": 2,
208 | "email": "alan@turing.com",
209 | "password": "iluvswpp",
210 | "name": "Alan Turing",
211 | "logged_in": false
212 | },
213 | {
214 | "id": 3,
215 | "email": "edsger@dijkstra.com",
216 | "password": "iluvswpp",
217 | "name": "Edsger Dijkstra",
218 | "logged_in": false
219 | }
220 | ]
221 | }
222 |
--------------------------------------------------------------------------------
/hw3/skeleton/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/vim,linux,macos,python,django,pycharm,windows,intellij
3 | # Edit at https://www.gitignore.io/?templates=vim,linux,macos,python,django,pycharm,windows,intellij
4 |
5 | ### Django ###
6 | *.log
7 | *.pot
8 | *.pyc
9 | __pycache__/
10 | local_settings.py
11 | db.sqlite3
12 | db.sqlite3-journal
13 | media
14 |
15 | # If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/
16 | # in your Git repository. Update and uncomment the following line accordingly.
17 | # /staticfiles/
18 |
19 | ### Django.Python Stack ###
20 | # Byte-compiled / optimized / DLL files
21 | *.py[cod]
22 | *$py.class
23 |
24 | # C extensions
25 | *.so
26 |
27 | # Distribution / packaging
28 | .Python
29 | build/
30 | develop-eggs/
31 | dist/
32 | downloads/
33 | eggs/
34 | .eggs/
35 | lib/
36 | lib64/
37 | parts/
38 | sdist/
39 | var/
40 | wheels/
41 | pip-wheel-metadata/
42 | share/python-wheels/
43 | *.egg-info/
44 | .installed.cfg
45 | *.egg
46 | MANIFEST
47 |
48 | # PyInstaller
49 | # Usually these files are written by a python script from a template
50 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
51 | *.manifest
52 | *.spec
53 |
54 | # Installer logs
55 | pip-log.txt
56 | pip-delete-this-directory.txt
57 |
58 | # Unit test / coverage reports
59 | htmlcov/
60 | .tox/
61 | .nox/
62 | .coverage
63 | .coverage.*
64 | .cache
65 | nosetests.xml
66 | coverage.xml
67 | *.cover
68 | .hypothesis/
69 | .pytest_cache/
70 |
71 | # Translations
72 | *.mo
73 |
74 | # Scrapy stuff:
75 | .scrapy
76 |
77 | # Sphinx documentation
78 | docs/_build/
79 |
80 | # PyBuilder
81 | target/
82 |
83 | # pyenv
84 | .python-version
85 |
86 | # pipenv
87 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
88 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
89 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
90 | # install all needed dependencies.
91 | #Pipfile.lock
92 |
93 | # celery beat schedule file
94 | celerybeat-schedule
95 |
96 | # SageMath parsed files
97 | *.sage.py
98 |
99 | # Spyder project settings
100 | .spyderproject
101 | .spyproject
102 |
103 | # Rope project settings
104 | .ropeproject
105 |
106 | # Mr Developer
107 | .mr.developer.cfg
108 | .project
109 | .pydevproject
110 |
111 | # mkdocs documentation
112 | /site
113 |
114 | # mypy
115 | .mypy_cache/
116 | .dmypy.json
117 | dmypy.json
118 |
119 | # Pyre type checker
120 | .pyre/
121 |
122 | ### Intellij ###
123 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
124 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
125 |
126 | # User-specific stuff
127 | .idea/**/workspace.xml
128 | .idea/**/tasks.xml
129 | .idea/**/usage.statistics.xml
130 | .idea/**/dictionaries
131 | .idea/**/shelf
132 |
133 | # Generated files
134 | .idea/**/contentModel.xml
135 |
136 | # Sensitive or high-churn files
137 | .idea/**/dataSources/
138 | .idea/**/dataSources.ids
139 | .idea/**/dataSources.local.xml
140 | .idea/**/sqlDataSources.xml
141 | .idea/**/dynamic.xml
142 | .idea/**/uiDesigner.xml
143 | .idea/**/dbnavigator.xml
144 |
145 | # Gradle
146 | .idea/**/gradle.xml
147 | .idea/**/libraries
148 |
149 | # Gradle and Maven with auto-import
150 | # When using Gradle or Maven with auto-import, you should exclude module files,
151 | # since they will be recreated, and may cause churn. Uncomment if using
152 | # auto-import.
153 | # .idea/modules.xml
154 | # .idea/*.iml
155 | # .idea/modules
156 | # *.iml
157 | # *.ipr
158 |
159 | # CMake
160 | cmake-build-*/
161 |
162 | # Mongo Explorer plugin
163 | .idea/**/mongoSettings.xml
164 |
165 | # File-based project format
166 | *.iws
167 |
168 | # IntelliJ
169 | out/
170 |
171 | # mpeltonen/sbt-idea plugin
172 | .idea_modules/
173 |
174 | # JIRA plugin
175 | atlassian-ide-plugin.xml
176 |
177 | # Cursive Clojure plugin
178 | .idea/replstate.xml
179 |
180 | # Crashlytics plugin (for Android Studio and IntelliJ)
181 | com_crashlytics_export_strings.xml
182 | crashlytics.properties
183 | crashlytics-build.properties
184 | fabric.properties
185 |
186 | # Editor-based Rest Client
187 | .idea/httpRequests
188 |
189 | # Android studio 3.1+ serialized cache file
190 | .idea/caches/build_file_checksums.ser
191 |
192 | ### Intellij Patch ###
193 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
194 |
195 | # *.iml
196 | # modules.xml
197 | # .idea/misc.xml
198 | # *.ipr
199 |
200 | # Sonarlint plugin
201 | .idea/**/sonarlint/
202 |
203 | # SonarQube Plugin
204 | .idea/**/sonarIssues.xml
205 |
206 | # Markdown Navigator plugin
207 | .idea/**/markdown-navigator.xml
208 | .idea/**/markdown-navigator/
209 |
210 | ### Linux ###
211 | *~
212 |
213 | # temporary files which can be created if a process still has a handle open of a deleted file
214 | .fuse_hidden*
215 |
216 | # KDE directory preferences
217 | .directory
218 |
219 | # Linux trash folder which might appear on any partition or disk
220 | .Trash-*
221 |
222 | # .nfs files are created when an open file is removed but is still being accessed
223 | .nfs*
224 |
225 | ### macOS ###
226 | # General
227 | .DS_Store
228 | .AppleDouble
229 | .LSOverride
230 |
231 | # Icon must end with two \r
232 | Icon
233 |
234 | # Thumbnails
235 | ._*
236 |
237 | # Files that might appear in the root of a volume
238 | .DocumentRevisions-V100
239 | .fseventsd
240 | .Spotlight-V100
241 | .TemporaryItems
242 | .Trashes
243 | .VolumeIcon.icns
244 | .com.apple.timemachine.donotpresent
245 |
246 | # Directories potentially created on remote AFP share
247 | .AppleDB
248 | .AppleDesktop
249 | Network Trash Folder
250 | Temporary Items
251 | .apdisk
252 |
253 | ### PyCharm ###
254 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
255 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
256 |
257 | # User-specific stuff
258 |
259 | # Generated files
260 |
261 | # Sensitive or high-churn files
262 |
263 | # Gradle
264 |
265 | # Gradle and Maven with auto-import
266 | # When using Gradle or Maven with auto-import, you should exclude module files,
267 | # since they will be recreated, and may cause churn. Uncomment if using
268 | # auto-import.
269 | # .idea/modules.xml
270 | # .idea/*.iml
271 | # .idea/modules
272 | # *.iml
273 | # *.ipr
274 |
275 | # CMake
276 |
277 | # Mongo Explorer plugin
278 |
279 | # File-based project format
280 |
281 | # IntelliJ
282 |
283 | # mpeltonen/sbt-idea plugin
284 |
285 | # JIRA plugin
286 |
287 | # Cursive Clojure plugin
288 |
289 | # Crashlytics plugin (for Android Studio and IntelliJ)
290 |
291 | # Editor-based Rest Client
292 |
293 | # Android studio 3.1+ serialized cache file
294 |
295 | ### PyCharm Patch ###
296 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
297 |
298 | # *.iml
299 | # modules.xml
300 | # .idea/misc.xml
301 | # *.ipr
302 |
303 | # Sonarlint plugin
304 |
305 | # SonarQube Plugin
306 |
307 | # Markdown Navigator plugin
308 |
309 | ### Python ###
310 | # Byte-compiled / optimized / DLL files
311 |
312 | # C extensions
313 |
314 | # Distribution / packaging
315 |
316 | # PyInstaller
317 | # Usually these files are written by a python script from a template
318 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
319 |
320 | # Installer logs
321 |
322 | # Unit test / coverage reports
323 |
324 | # Translations
325 |
326 | # Scrapy stuff:
327 |
328 | # Sphinx documentation
329 |
330 | # PyBuilder
331 |
332 | # pyenv
333 |
334 | # pipenv
335 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
336 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
337 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
338 | # install all needed dependencies.
339 |
340 | # celery beat schedule file
341 |
342 | # SageMath parsed files
343 |
344 | # Spyder project settings
345 |
346 | # Rope project settings
347 |
348 | # Mr Developer
349 |
350 | # mkdocs documentation
351 |
352 | # mypy
353 |
354 | # Pyre type checker
355 |
356 | ### Vim ###
357 | # Swap
358 | [._]*.s[a-v][a-z]
359 | [._]*.sw[a-p]
360 | [._]s[a-rt-v][a-z]
361 | [._]ss[a-gi-z]
362 | [._]sw[a-p]
363 |
364 | # Session
365 | Session.vim
366 | Sessionx.vim
367 |
368 | # Temporary
369 | .netrwhist
370 | # Auto-generated tag files
371 | tags
372 | # Persistent undo
373 | [._]*.un~
374 |
375 | ### Windows ###
376 | # Windows thumbnail cache files
377 | Thumbs.db
378 | Thumbs.db:encryptable
379 | ehthumbs.db
380 | ehthumbs_vista.db
381 |
382 | # Dump file
383 | *.stackdump
384 |
385 | # Folder config file
386 | [Dd]esktop.ini
387 |
388 | # Recycle Bin used on file shares
389 | $RECYCLE.BIN/
390 |
391 | # Windows Installer files
392 | *.cab
393 | *.msi
394 | *.msix
395 | *.msm
396 | *.msp
397 |
398 | # Windows shortcuts
399 | *.lnk
400 |
401 | # End of https://www.gitignore.io/api/vim,linux,macos,python,django,pycharm,windows,intellij
402 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/hw3/README.md:
--------------------------------------------------------------------------------
1 | # Homework 3 - Django
2 |
3 | **Due: 10/27 (Sun) 18:00 (This is a hard deadline)**
4 |
5 | ## Django
6 |
7 | In this assignment you will implement a backend service for the blog frontend that you have created in homework 2.
8 | This is an **individual** assignment.
9 |
10 | Through this assignment, you are expected to:
11 |
12 | - Build a RESTful API server with Django (2.2.6)
13 | - Understand how communication between the client and the server occurs
14 | - Test your Django application
15 |
16 | ### Comments on files
17 |
18 | Our `myblog` project consists of a single app, `blog`.
19 | Because we provide the url routing and setting of the project already, you are expected to update the `blog` app mainly.
20 |
21 | ### Features
22 |
23 | As you have seen in homework 2, our blog has three models: User, Article, and Comment.
24 |
25 | - Each user should be able to sign up, sign in and sign out.
26 | - Only those users who are signed in are allowed to read or write articles and comments.
27 | - Users should be able to update or delete articles and comments only which they have created.
28 |
29 | For the user model, you **must** use the [Django default user model](https://docs.djangoproject.com/en/2.2/topics/auth/) and the django authentication system to manage user authentication.
30 | In homework 2, we didn't cover the real user authentication process.
31 | Now with a proper backend, we can manage user sessions and authentication supported by Django.
32 |
33 | For articles, you need to create a model named as `Article` that consists of following fields:
34 |
35 | | Field name | Type |
36 | |------------------------|-----|
37 | | `title` | Char Field (max_length=64) |
38 | | `content` | Text Field |
39 | | `author` | Foreign Key |
40 |
41 | The author must be a (foreign) key referring a User.
42 |
43 | For comments, you need to create a model named as `Comment` that consists of following fields:
44 |
45 | | Field name | Type |
46 | |------------------------|-----|
47 | | `article` | Foreign Key |
48 | | `content` | Text Field |
49 | | `author` | Foreign Key |
50 |
51 | The article and author must be a (foreign) key referring an Article and a User.
52 |
53 | 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).
54 |
55 | ```
56 | from .models import Article, Comment
57 |
58 | new_user = User.objects.create_user(username='swpp', password='iluvswpp') # Django default user model
59 | new_article = Article(title='I Love SWPP!', content='Believe it or not', author=new_user)
60 | new_article.save()
61 | new_comment = Comment(article=new_article, content='Comment!', author=new_user)
62 | new_comment.save()
63 | ```
64 |
65 | Detailed specifications of RESTful APIs are as following:
66 |
67 | | API | GET | POST | PUT | DELETE |
68 | |------------------------|-----|------|-----|--------|
69 | | `api/signup` | X | Create new user | X | X |
70 | | `api/signin` | X | Log in | X | X |
71 | | `api/signout` | Log out | X | X | X |
72 | | `api/article` | Get article list | Create new article | X | X |
73 | | `api/article/:article_id` | Get specified article | X | Edit specified article | Delete specified article |
74 | | `api/article/:article_id/comment` | Get comments of specified article | Create comment on specified article | X | X |
75 | | `api/comment/:comment_id` | Get specified comment | X | Edit specified comment | Delete specified comment |
76 |
77 | Note that the APIs are slightly different from that of homework 2. Since we have used simple json server backend, APIs were limited in homework 2.
78 | In this assignment, we will implement a more RESTful API.
79 |
80 | POST and PUT requests should contain data using the JSON format in the body of the request.
81 | For each model, the JSON format should look like:
82 |
83 | - User : `{username: string, password: string}`
84 | - Article : `{title: string, content: string}`
85 | - Comment : `{content: string}`
86 |
87 | Also, the user information will be included in the `request` automatically. Check `request.user`.
88 |
89 | For each API you should respond with the appropriate HTTP response code.
90 | The list of response codes you should use is as follows:
91 |
92 | - `200` (Ok) : Request was responded successfully.
93 | - `201` (Created) : Request has created new resources successfully.
94 | - `204` (No Content) : Request was responded successfully but without any content.
95 | - `400` (Bad Request) : Failed to decode request body or failed to retrieve necessary key-value from json (`KeyError`).
96 | - `401` (Unauthorized) : Request requires authentication. This should be returned if you are requesting without signing in.
97 | - `403` (Forbidden) : Request is forbidden. This should be returned if your request tries to modify resources of which you are not the owner.
98 | - `404` (Not Found) : Requested resource is not found.
99 | - `405` (Method not allowed) : Requested URL does not allow the method of the request.
100 |
101 | Please make sure to implement your request methods under the following global specifications:
102 |
103 | - For all non-allowed requests (X marked in the API table), response with `405` (and any information must not be modified).
104 | - For all requests about article and comment without signing in, response with `401` (and any information must not be modified).
105 | - For all requests about non-existing article and comment, response with `404` (and any information must not be modified).
106 | - For all PUT and DELETE requests from non-author, response with `403` (and any information must not be modified).
107 |
108 | 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`.
109 |
110 | Also, please make sure to implement your request methods under the following detailed specifications (in your `views.py`). When the server successfully handles a request, it responds with a JSONResponse for GET and responds with a HTTPResponse for POST, PUT, and DELETE.
111 |
112 | - POST `api/signup`:
113 |
114 | Create a user with the information given by request JSON body and response with `201`
115 | - POST `api/signin`:
116 |
117 | 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`.
118 | - GET `api/signout`:
119 |
120 | If the user is authenticated, log-out (the authentication info should be changed properly) and response with `204`. If not, response with `401`.
121 | - GET `api/article`:
122 |
123 | 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`.
124 | - POST `api/article`:
125 |
126 | Create an article with the information given by request JSON body and response with `201`. Posted article (with it's assigned id) should be included in response's content as JSON format.
127 | - GET `api/article/:article_id`:
128 |
129 | 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`.
130 | - PUT `api/article/:article_id`:
131 |
132 | Update the target article with the information given by request JSON body and response with `200`. Updated article (with it's id) should be included in response's content as JSON format.
133 | - DELETE `api/article/:article_id`:
134 |
135 | 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.
136 | - GET `api/article/:article_id/comment`:
137 |
138 | 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`.
139 | - POST `api/article/:article_id/comment`:
140 |
141 | Create a comment with the information given by request JSON body and response with `201`. Posted comment (with it's assigned id) should be included in response's content as JSON format.
142 | - GET `api/comment/:comment_id`:
143 |
144 | 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`.
145 | - PUT `api/comment/:comment_id`:
146 |
147 | Update the target comment with the information given by request JSON body and response with `200`. Updated comment (with it's id) should be included in response's content as JSON format.
148 | - DELETE `api/comment/:comment_id`:
149 |
150 | Delete the target comment and response with `200`. When deleting a comment, other users, articles and comments **must** not be deleted also.
151 |
152 | ### Testing
153 |
154 | You should also write tests to verify that your blog backend is implemented correctly.
155 | Your tests should reach **100%** of both the statement coverage and the branch coverage.
156 |
157 | You can run tests and gather coverage data by:
158 | - Statement coverage : `coverage run --source='./blog' manage.py test`
159 | - Branch coverage : `coverage run --branch --source='./blog' manage.py test`
160 |
161 | Use `coverage report -m` to report on the results.
162 | Use `coverage html` for a nicer presentation.
163 |
164 | ### Tips
165 |
166 | 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.2/ref/csrf/).
167 | To successfully handle such requests, try the following steps:
168 |
169 | 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.
170 | 2. Send the POST request with a header containing `HTTP_X_CSRFTOKEN` as the value of the `csrftoken`.
171 |
172 | For more detail, see `test_csrf` of the `blog/test.py` file in the skeleton code.
173 | You may change this part if you have a better way of handling the CSRF token, but disabling the protection itself is **NOT** permitted.
174 |
175 | To test your APIs, we recommend using ARC (Advanced REST Client). Check `arc.pdf` for detailed information.
176 |
177 | ## Grading
178 |
179 | This assignment is composed of a total of 80 points.
180 | We will test your Django code under Python 3.6.
181 |
182 | - User APIs (15 points)
183 | - Article APIs (20 points)
184 | - Comment APIs (20 points)
185 | - Django Testing (25 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: 10/27 (Sun) 18:00 (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 `ktaebum`, `kyunggeun-lee`, and `hy00nc` 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 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 | README.md (this file)
206 | blog/
207 | ...
208 | myblog/
209 | ...
210 | manage.py
211 | ...
212 | ```
213 |
--------------------------------------------------------------------------------
/hw1/README.md:
--------------------------------------------------------------------------------
1 | # Homework 1 - Python and JavaScript Basics
2 |
3 | **Due: 9/15 (Sun) 18:00 (This is a hard deadline)**
4 |
5 | This assignment is for you to become familiar with Python and JavaScript.
6 | You will be using Python to build a backend system, and JavaScript to build a (separated) frontend system, using the React framework in hw2 and hw3.
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 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 | ## JavaScript
111 |
112 | Each of the files serve the following roles:
113 |
114 | - `form.html` : HTML file for layout for the form checking page.
115 | - `form.js` : JavaScript file for form checking and using JS components.
116 |
117 | 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.
118 | 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.
119 | 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.
120 |
121 | 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.
122 |
123 | ### JavaScript Form Checker
124 |
125 | To complete this assignment, you will have to implement a form checker, with tooltips, and modal pop-ups using JavaScript. Through this assignment, we expect you to be able to:
126 |
127 | - See usages of JavaScript
128 | - Try out basic and most common usages of JavaScript
129 | - Some taste of JavaScript before diving into React with HW2.
130 |
131 | When you open `form.html`, you will see the following screen on your browser.
132 |
133 | 
134 |
135 | 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.
136 | If you push the "check" button, you will see an empty popup.
137 |
138 | You need to provide following features by completing `form.js`:
139 |
140 | **1) form validation popup**
141 |
142 | 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).
143 | If there is no problem with the form, it should show a modal indicating that it had been successfully submitted.
144 | Specific **requirements** are as listed below.
145 | - Email: 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.
146 | - `characters(except for whitespace and '@')` **@** `characters(except for whitespace, '@' and '.')` **.** `2-3 alphabets`
147 | - *characters* mean one or more characters including alphabets, numbers or special characters.
148 | - *alphabets* include both lowercase and uppercase.
149 | - e.g.) valid@javascript.com (O), invalid@snu.ac.kr (X)
150 | - Password: Must contain at least one number and one uppercase and one lowercase letter, and at least 8 or more characters.
151 | - Password Confirmation: Must match password.
152 | - Phone number: nnn-nnnn-nnnn: three numbers, then "-", followed by four numbers and a "-", then four numbers.
153 | - First name (English) : Start with a capital letter, followed by one or more lowercase letters. Should only contain alphabets (A-Z, a-z)
154 | - Last name (English) : Start with a capital letter, followed by one or more lowercase letters. Should only contain alphabets (A-Z, a-z)
155 | - Age : Must be a number between 0 and 200 (inclusive).
156 | - Birth date (Month) : Must be one of "January", "February", ..., "December"
157 | - Birth date (Day) : Must be a number of one or two digits.
158 | - Birth date (Year) : Must be a number between 1800 and 2018 (inclusive).
159 |
160 | If the form does not satisfy the requirements (for example, if Email, Password, and Password Confirmation fail), the alert message **must** be like:
161 | ```
162 | You must correct:
163 |
164 | Email
165 | Password
166 | Password Confirmation
167 | ```
168 | 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.
169 |
170 | If the form satisfies the requirements, the alert message **must** be:
171 | ```
172 | Successfully Submitted!
173 | ```
174 |
175 | **2) correct label and tooltip**
176 |
177 | 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.
178 |
179 | 
180 |
181 | The error message in that tooltip **must** be identical with each requirement above.
182 | Also, if an entry becomes valid after another check, the 'X' label have to be disappeared.
183 |
184 | Tip: using regex might be useful for detecting wrong forms
185 |
186 | ## Grading
187 |
188 | ### Python (10 points)
189 |
190 | We will test your code under Python 3.6.
191 |
192 | - `check_filename_existence` decorator method in `babyname_parser.py` (2 points)
193 | - `parse` method in `babyname_parser.py` (4 points) (automatically include the `__init__` constructor)
194 | - `run.py` (4 points)
195 | - Partial points for minor errors
196 |
197 | ### JavaScript (10 points)
198 |
199 | We will grade the `form.js` and `form.html` file under the `javascript` directory in your GitHub repository.
200 | We will see the outputs to validate your answers.
201 |
202 | - Valid form checking with proper alert message (5 points)
203 | - Label (proper 'X') and modal tooltips (5 points)
204 | - Partial points for minor errors
205 |
206 |
207 | ## Submission
208 |
209 | Due: 9/15 (Sun) 18:00 (This is a hard deadline)
210 |
211 | You must create your own *private* repository under your account ~~and **send them by email to `swpp-tas@spl.snu.ac.kr`**~~.
212 | **Be sure to add the TAs as collaborators in your repository settings!** (Detailed instructions below).
213 | We will check the snapshot of the *master* branch of your Github repository at the deadline and grade it.
214 | Please create a `python` and `javascript` folders, and put your homework files in them appropriately.
215 | 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:
216 | ```
217 | repository_root/
218 | README.md (this file)
219 | python/
220 | baby1994.html
221 | babyname_parser.py
222 | run.py
223 | ...
224 | javascript/
225 | form.html
226 | form.js
227 | ...
228 | ```
229 | Also, make sure to push your work on Github on time.
230 |
231 | ### Instructions on creating a private repository
232 |
233 | #### I. Get GitHub Student Developer Pack
234 |
235 | 1. Go to `https://education.github.com`.
236 | 2. Follow instructions to `Request a discount`.
237 |
238 | #### II. Make your private repository
239 |
240 | 1. Go to your github profile: `https://github.com/YOUR_USERNAME`.
241 | 2. Under `Repositories`, click on `New`.
242 | 3. Fill in `swpp-hw1-USERNAME` as your repository name, and mark is as `Private`. (e.g., `swpp-hw1-ktaebum`)
243 | 4. Hit `Create repository`.
244 | 5. In terminal, go to the directory that you will be working in (e.g., `~/workspace/swpp-hw1-USERNAME` or `~/swpp-hw1-USERNAME`)
245 | 6. Type in and run the following commands, which is also shown on the page that you will be looking at after step 4:
246 |
247 | ```
248 | echo "# asdf" >> README.md
249 | git init
250 | git add README.md
251 | git commit -m "first commit"
252 | git remote add origin https://github.com/USERNAME/swpp-hw1-USERNAME
253 | git push -u origin master
254 | ```
255 |
256 | Alternatively you can start by copying skeleton codes :)
257 | ```
258 | cp -r ${swppfall2019-home}/hw1 ~/workspace/swpp-hw1-USERNAME
259 | git init
260 | git add .
261 | git commit -m "first commit"
262 | git remote add origin https://github.com/USERNAME/swpp-hw1-USERNAME
263 | git push -u origin master
264 | ```
265 |
266 | 7. Under `Settings` then `Collaborators` tab, Add TAs as your collaborators: `ktaebum`, `kyunggeun-lee`, and `hy00nc`.
267 | 8. You're all set! After finishing your homework, push your contents to your repository on time!
268 |
--------------------------------------------------------------------------------
/hw2/README.md:
--------------------------------------------------------------------------------
1 | # Homework 2 - React Library & Testing
2 |
3 | #### **Due (These are hard deadlines)**
4 | - ##### **Feature Implementation Due: 10/4 (Fri) 18:00**
5 | - ##### **Testing Implementation Due: 10/11 (Fri) 18:00**
6 |
7 | You will implement a front-end for a blogging service using React library. This is an **individual** assignment.
8 | This assignment will help you
9 |
10 | - Make a simple React (version 16.9.0) application before diving into your projects
11 | - Make test suites for the React application you implement
12 | - Let you try out stuff we have learned in our practice sessions
13 |
14 | ## Features
15 |
16 | Our blog will support three models: User, Articles, and Comments.
17 | You are required to create a total of five pages as shown in the below storyboard, meeting the following requirements:
18 |
19 | 
20 |
21 | - Log In page (`/login`)
22 | - You must have the following fields:
23 |
24 | | JSX Tag type | id |
25 | |---------------|--|
26 | | input | email-input |
27 | | input | pw-input |
28 | | button | login-button |
29 |
30 | - Users should be able to log-in by filling up the email and password inputs and hitting the log-in button.
31 | - 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'.
32 | - When a user tries to log-in with invalid inputs, the frontend should emit `Email or password is wrong` message through `alert` command (in Javascript).
33 | - After logging-in, users should find themselves at the article list page. (`/articles`)
34 | - 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!
35 | - Article list page (`/articles`)
36 | - 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.
37 | - Also, user must be able to go to article create page (`/articles/create`) by hitting:
38 |
39 | | JSX Tag type | id |
40 | |-------------|--|
41 | | button | create-article-button |
42 |
43 | - 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`.
44 | - Article write(create) page (`/articles/create`)
45 | - You must have the following fields in Write tab:
46 |
47 | | JSX Tag type | id |
48 | |-------------|--|
49 | | input or textarea | article-title-input |
50 | | input or textarea | article-content-input |
51 | | button | back-create-article-button |
52 | | button | confirm-create-article-button |
53 | | button | preview-tab-button |
54 | | button | write-tab-button |
55 |
56 | - Also, you must have the following fields in Preview tab:
57 |
58 | | JSX Tag type | id |
59 | |-------------|--|
60 | | any plain text (like h1, h3, p, …) | article-author |
61 | | any plain text (like h1, h3, p, …) | article-title |
62 | | any plain text (like h1, h3, p, …) | article-content |
63 | | button | back-create-article-button |
64 | | button | confirm-create-article-button |
65 | | button | preview-tab-button |
66 | | button | write-tab-button |
67 |
68 | - 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.
69 | - The created article, of course, should be tagged with your own author id.
70 | - After creating the article, the user should be redirected to the created article's detail page (`/articles/:id`)
71 | - 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.
72 | - 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`.
73 | - If the title or content input are empty, the confirm button should be disabled.
74 | - The back button will go back to the article list page (`/articles`) (also without any alert).
75 | - Article detail page (`/articles/:id`)
76 | - You must have the following fields:
77 |
78 | | JSX Tag type | id |
79 | |-------------|--|
80 | | any plain text (like h1, h3, p, …) | article-author |
81 | | any plain text (like h1, h3, p, …) | article-title |
82 | | any plain text (like h1, h3, p, …) | article-content |
83 | | input or textarea | new-comment-content-input |
84 | | button | confirm-create-comment-button |
85 | | button | edit-comment-button |
86 | | button | delete-comment-button |
87 | | button | edit-article-button |
88 | | button | delete-article-button |
89 | | button | back-detail-article-button |
90 |
91 | - Users should be able to clearly make out the title, contents, and author name of the article.
92 | - Also, users should be able to see the whole comments for the corresponding article including the author name and contents of each comments.
93 | - Simple comments functionalities (Create for everyone / Edit/Delete for the comment author through the buttons) should work.
94 | - 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). However, `confirm-create-comment-button` should be disabled when the `new-comment-content-input` is empty.
95 | - When a user hits the `edit-comment-button`, a `prompt` taking some string input should be popped up (by using Javascript `prompt` command) and initial value of the prompt should be same as current comment's content
96 | - 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.
97 | - When the user confirm the pop-up with empty content, the contents should not be modified (consistent to `user cannot create empty comment`)
98 | - When the user canceled the pop-up, the contents should not be modified.
99 | - When a user hits the `delete-comment-button`, the comment should be deleted without any alert.
100 | - The edit and delete button for each comment must be visible for the author only.
101 | - Edit/Delete button for the article should work.
102 | - These buttons must be visible for the author only.
103 | - When a user hit the `edit-article-button`, the user should be redirected to the edit page (`articles/:id/edit`)
104 | - 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.
105 | - When a user hits `back-detail-article-button` button, the user should be redirected to the article list page.
106 | - Article edit page (`/articles/:id/edit`)
107 | - You must have the following fields in Write tab:
108 |
109 | | JSX Tag type | id |
110 | |-------------|--|
111 | | input or textarea | article-title-input |
112 | | input or textarea | article-content-input |
113 | | button | back-edit-article-button |
114 | | button | confirm-edit-article-button |
115 | | button | preview-tab-button |
116 | | button | write-tab-button |
117 |
118 | - Also, you must have the following fields in Preview tab:
119 |
120 | | JSX Tag type | id |
121 | |-------------|--|
122 | | any plain text (like h1, h3, p, …) | article-author |
123 | | any plain text (like h1, h3, p, …) | article-title |
124 | | any plain text (like h1, h3, p, …) | article-content |
125 | | button | back-edit-article-button |
126 | | button | confirm-edit-article-button |
127 | | button | preview-tab-button |
128 | | button | write-tab-button |
129 |
130 | - 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).
131 | - However, the `article-title-input` should contains current article's title and `article-content-input` should contains current article's content
132 | - 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.
133 | - When a user hits `back-edit-article-button`, the following features should be supported:
134 | - 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.
135 | - If the title or contents has been modified modified, you should make a confirmation pop-up (through Javascript `confirm` command) with message `Are you sure? The change will be lost.`
136 | - 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.
137 | - If the user dismiss the confirmation, the user should just stay on the edit page and be able to resume editing.
138 | - If the title or content input are empty, the confirm button should be disabled (consistent to `/create`).
139 | - Common things for **all pages**:
140 | - If the user is logged-in, the user should be able to log-out from any of the pages by clicking `logout-button`. Upon logging-out, the user should end on the initial Log In page (shown as dotted lines on the storyboard).
141 |
142 |
143 | | JSX Tag type | id |
144 | |---------------|--|
145 | | button | logout-button |
146 |
147 | - Each user should be able to update or delete articles and comments only which they have created.
148 | - **All pages/components should have proper unit tests to test its functionalities, using Jest and Enzyme that are covered in 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 by using `npm test -- --coverage`. Also, all of your tests must pass.**
149 |
150 | We provide a simple [json-server](https://github.com/typicode/json-server) backend with our skeleton code (`skeleton/api`).
151 | 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.
152 |
153 | To run server, just type following command at the root of the project
154 | ```
155 | $ yarn install (only for the first time)
156 | $ yarn run backend (or npm run backend)
157 | ```
158 |
159 | You should be able to implement your redux action creators by sending appropriate http requests to the following URLs:
160 |
161 | | API | GET | POST | PUT | DELETE |
162 | |------------------------|-----|------|-----|--------|
163 | | `api/user` | Get user list | X | X | X |
164 | | `api/user/1` | Get user information containing whether or not the user is logged_in | X | Update user's `logged_in` value to log-in/log-out | X |
165 | | `api/articles` | Get article list | Create new article | X | X |
166 | | `api/articles/:id` | Get specified article | X | Edit specified article | Delete specified article |
167 | | `api/comments` | Get comments | Create new comment | X | X |
168 | | `api/comments/:id` | Get specified comment | X | Edit specified comment | Delete specified comment |
169 |
170 | Articles should have an `id` (number), `author_id` (number), `title` (string), and `content` (string).
171 | Comments should have an `id` (number), `author_id` (number), `article_id` (number), and `content` (string).
172 | Users should have an `id` (number), `email` (string), `password` (string), `name` (string), and `logged_in` (boolean).
173 |
174 | Each field names are as specified above. You should be able to implement the pages required with these APIs.
175 |
176 | ## Comments on files
177 |
178 | Files that are created inside the `skeleton` (root) and `src` folder have been already discussed during the practice session (contents in [this link](https://github.com/facebook/create-react-app)). As we have done so in our practice sessions, you are expected to add proper components, containers, redux-store (actions, reducers) under the `src/` directory freely, according to your needs. Nicely refactored code will result in better readability and is recommended.
179 |
180 | The `skeleton/api` directory is added to provide simple backend for you to test out your application, and serves as specified above. **Please do not modify this directory.** You are expected to create `store` that manages redux-store by communicating using HTTP, and `containers` and `components` that produce each pages' requirements. The existing `App.js` is expected to be the root component of the entire application.
181 | Also, please do not make any un-requested alerts. It will largely harm the e2e test result.
182 | We will test your code after conducting `yarn install`, so you can import other libraries through `package.json`. However, you should not change the version of already imported dependencies.
183 |
184 | ## Tips
185 |
186 | - Most of things have been covered in the tutorial during the lab session. Please look carefully through the slides and the tips provided.
187 | - It might be useful and more pleasing to the eyes by using a CSS framework like [Bootstrap-React](https://react-bootstrap.github.io/) and [SemanticUI-React](https://react.semantic-ui.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.
188 |
189 | ## Grading
190 |
191 | This assignment is composed of a total of 80 points. We will score your feature implementation (**lastest commit before 4 October 6:00 PM**) 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. Also, we will check your unit test coverage (**latest commit before 11 October 6:00 PM**), which is 25 points in total. Grading details are shown below.
192 |
193 | ### Feature Implementation Score
194 | The e2e test consist of cases about:
195 | - Log in page features (4 points)
196 | - Article list page features (5 points)
197 | - Article create page features (10 points)
198 | - Article detail page features when the user is the author of the article (14 points)
199 | - Article detail page features when the user is not the author of the article (13 points)
200 | - Article edit page features (9 points)
201 |
202 | ### Unit Test Score
203 | Your unit test score will be given based on both test coiverage and completeness of your feature implementation.
204 | This is to make sure that your test code is faithful to the feature requirements.
205 | To be more precise, your unit test score will be given as follows:
206 | (*scorefeature* denotes your feature implementation score)
207 |
208 | |
|
215 |
216 | *Note: All your test cases must pass*
217 |
218 |
219 |
220 | Since we will automatically score your homework, **please make sure that you follow the features specification (especially, the Tag type and id of JSX fields)**.
221 | Also, if some basic features are not implemented properly, many other test cases can fail. For example, if the logging-in process works badly, most of the cases above will fail.
222 | We'll try to give some partial points in this case, but it might not be enough.
223 | It's a good idea to start with the log-in page, and then implement routing features, article list pages, and other features in order.
224 | Finally, since you have to implement many features, start early!
225 |
226 | ## Submission
227 |
228 | **Due: (These are hard deadlines)**
229 | - **Feature Implementation Due: 10/4 (Fri) 18:00**
230 | - **Testing Implementation Due: 10/11 (Fri) 18:00**
231 |
232 | We will check the snapshot of the *master* branch of your Github repository at the deadline and grade it.
233 | Please name your repository as `swpp-hw2-YOUR_USERNAME`, and replace YOUR_USERNAME with your own GitHub username. Please note that USERNAME is case-sensitive.
234 | Refer to HW1 to create another private repository.
235 |
236 | Please put your React application files in the root folder (not inside another `hw2` or `skeleton` folder) appropriately.
237 | We automatize the grading process, so your homework may not be graded properly if your directory hierarchy doesn't look like this:
238 |
239 | ```
240 | repository_root/
241 | api/
242 | public/
243 | src/
244 | App.js
245 | App.test.js
246 | index.js
247 | ...
248 | package.json
249 | ...
250 | ```
251 | Also, please include proper `.gitignore` file so redundant items are not be pushed to your repository (like `node_modules`).
252 | You can use skeleton code's `.gitignore` file.
253 |
254 | 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.
255 |
--------------------------------------------------------------------------------
/hw1/python/baby1994.html:
--------------------------------------------------------------------------------
1 | Popular Baby Names
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |