Developing with Frontend & Backend
To get started with development, you need tools. You'll learn how to get the necessary tools here using Conda scripts.
GitHub
- What is GitHub?
A website called GitHub is utilized by programmers as a center for sharing code and programs.
- Why do we use GitHub? Why not Google Drive or messages?
GitHub was created with programming in mind. It is coupled with the "git" code repository system.
- What's the difference between Git and GitHub?
Git is a tool that lets you store code and share it with the world via a handful of instructions. The website where people contribute their code is called GitHub.
- Name as many Git commands as you can:
Clone Fork Commit Config Sync Pull Push Rebase Refork
Two Main Machines
- Which is better, MacOS or Windows?
Linux is the best, not either.
- Give some differences between MacOS and Windows in terms of the development we use in APCSP:
Windows employs the Windows NT operating system, whereas MacOS uses Unix. Because Unix is integrated into many different systems and programs, it is developer friendly. Windows employs the Windows NT operating system, whereas MacOS uses Unix. Because Unix is integrated into many different systems and programs, it is developer friendly.
- If you are on Windows, you want to skip the MacOS Setup instructions.
Our Tools:
- What is the first tool you remember installing?
Homebrew was the first application I can recall installing because I am aware that the last time I did so, it gave me a lot of trouble.
- Why was installations so hard the first time?
It was challenging to comprehend how to utilize Terminal or bash commands, in addition to the fact that I had installed several things previously and had issues upgrading and reconfiguring them. I had no idea how to fix problems when they occurred.
- Without looking back at previous notes, name three tools you remember installing. This can be kernels, extensions, any installation for APCSP, and also write why it is needed.
I can still recall setting up homebrew, which generates a number of executables not included with Mac operating systems and allows you to perform a wide range of tasks, including working with Gems. I can still recall downloading VSCode and using my GitHub account to log in, which enabled me to create this blog and commit it to my GitHub. The first obviously allowed my system to comprehend Python code, and the later served as a container for my default Python version and other programs that go along with it like Jupyter Notebooks. I can still recall installing Python and Anaconda along with it.
Actual Installations:
Tool setup is a week 0 thing. You should already have the knowledge to set up your machine. There is also a high chance you had to remove your environments and set up your machine again due to errors. If, for some reason, these don't apply to you, go here to set up your machine, here to check everything working with Bash, and here for Docker setup, which are the main tools on our machine needed to develop in APCSP.
brew list # list packages
brew update # update package list
brew upgrade # upgrade packages
brew install git # install latest git
brew install python # install python3 for development
python --version # version of python3 installed
brew install java # openjdk install
wsl --install
wsl --list
wsl --install -d Ubuntu-20.04
# restart machine
wsl
cd ~
mkdir vscode
ls
cd ~/vscode # changes the directory to path for vscode files
git clone https://github.com/nighthawkcoders/APCSP.git # clone repo
cd APCSP # changes the directory to path for APCSP repos assets
code . # opens APCSP in VSCode
cd .. # changes the directory to the previous/parent directory
git config --global user.email mygmail@gmail.com # tell git your email
git config --global user.name mygithub # tell git your github id
shay@MSI:/mnt/c/Users/ShayM$ git config --global user.email your@email.here
shay@MSI:/mnt/c/Users/ShayM$ git config --global user.name yourusernamehere
# restart machine
PS C:\Users\UserName> wsl # Windows prompt to WSL command
cd /tmp
wget https://repo.anaconda.com/archive/Anaconda3-2022.05-Linux-x86_64.sh
chmod +x Anaconda3-2022.05-Linux-x86_64.sh
# Answer yes to all the prompts
./Anaconda3-2022.05-Linux-x86_64.sh
# run apt package commands now
sudo apt list # list packages
sudo apt update # update package list
sudo apt upgrade # upgrade packages
sudo apt install python2 # install python2 for package dependencies
sudo apt install python3 python3-pip # install python3 and pip3 for development
python --version # version of python3 should be shown
sudo apt install default-jdk default-jre # java install
java --version # java runtime version
javac --version # java compiler version
sudo apt install unzip # unzip utility
(base) id:~$ conda --version
(base) id:~$ conda install jupyter # install jupyter
(base) id:~$ jupyter kernelspec list # list installed kernels
Available kernels:
python3 /home/shay/.local/share/jupyter/kernels/python3
(base) id:~$ # start in home directory
(base) id:~$ pip install bash_kernel # download bash kernel
Collecting bash_kernel
Downloading bash_kernel-0.7.2-py2.py3-none-any.whl (15 kB)
Requirement already satisfied: pexpect>=4.0 in ./anaconda3/lib/python3.9/site-packages (from bash_kernel) (4.8.0)
Requirement already satisfied: ptyprocess>=0.5 in ./anaconda3/lib/python3.9/site-packages (from pexpect>=4.0->bash_kernel) (0.7.0)
Installing collected packages: bash-kernel
Successfully installed bash-kernel-0.7.2
(base) id:~$ python -m bash_kernel.install # install kernel
Installing IPython kernel spec
(base) id:~$ jupyter kernelspec list # list kernels
Available kernels:
bash /home/shay/.local/share/jupyter/kernels/bash
python3 /home/shay/.local/share/jupyter/kernels/python3
(base) id:~$ conda install nodejs # node is framework for JavaScript kernel
(base) id:~$ npm -version # node package manager comes with nodejs
(base) id:~$ npm install -g ijavascript # get the kernel
(base) id:~$ ijsinstall # install javascript kernel
(base) id:~$ jupyter kernelspec list # list kernels
Available kernels:
bash /home/shay/.local/share/jupyter/kernels/bash
javascript /home/shay/.local/share/jupyter/kernels/javascript
python3 /home/shay/.local/share/jupyter/kernels/python3
By now, you should already know how to clone Git repositories into your VSCode directory. Once you do that, you're all set for developing with GitHub Pages and Fastpages!
Before We Set Up Pages, A Guide to Git
As we've discussed, Git is different from GitHub. Because GitHub is merely the place where we store Git repos, we use Git's commands to help us get, open, and configure these repositories. Here are some of the Git commands you should be using a lot (In the comments, tell what each Git command does):
git clone {repos-name-here.git} # what does it do?
git checkout [branch] # what does it do?
git fork {repos-name-here.git} # what does it do?
git commit -m {"commit-msg"} # what does it do?
git pull # what does it do?
git push # what does it do?
# After this line, name other commands that you can use and what they do. This should be easy, as you've already answered the qeue
Setting Up GitHub Pages
Some of you may have come to know that GitHub Pages is starting to become outdated. So why do we still use it? The answer is that we are in a class, and following a curriculum with something like GitHub Pages is much easier than creating portfolio content from scratch, which becomes quite unecessary. Therefore, we can use GitHub Pages to create this content instead. On the topic of unecessary vs necessary coding, we don't need to make GitHub Pages from scratch as opposed to using a template that our very own Mr. Mortensen created for us. To do that, we can go to the Leuck Reunion repository and use the template to make our own GitHub Pages. Then, in Ubuntu, we can git clone
our repository and open it in VSCode. After we have it open, the last thing we want to do is set up local hosting for this website, so that we can preview it and make changes in real time. To do that, head here to install Jekyll for Ubuntu, here to install Ruby next, and here to finalize the process by installing Bundler.
Setting Up FastPages
In Setting Up Github Pages, we talked about how it is easier to use a template to create portfolio content. It is also easier to use a template when creating the portfolio itself. To do that, we can use Fastpages, which is what we have been using to show our blogs, code, and projects. However, Fastpages has been deprecated for some time now, so the instructions in Week 0 won't be effective. So, we need to fork the APCSP Fastpages. To do that, follow this video to get started developing with Fastpages.
Hacks
- Show how you incorporate three tools that we have installed into your project. 0.1 points for each feature. (0.3). This can include code, but definitely blog about it.
Git, which is used to clone, push, commit, add, etc., was also installed. It's quite helpful for performing AWS patches and ensuring that vscode and deployed servers are current with updates.A method that filters data that is fetched from the backend was written using javascript. on order to actually access the data on the backend, a fetch method is also written in javascript.
<style>
#navigation{
font-family: 'Fira Mono', monospace !important;
min-width: fit-content !important;
max-height: fit-content !important;
}
.home, .bighome{
text-align: center;
}
#logOut{
min-width: fit-content;
background-color: rgb(223, 109, 109);
max-height: 30px !important;
padding: 5px;
margin: 0px !important;
}
</style>
<table id = "navigation">
<tr class = bighome>
<td class = "home"><a href="{{site.baseurl}}/leaderboard"><nav>Leaderboard</nav></a></td>
<td class = "home"><a href="{{site.baseurl}}/game"><nav>Game</nav></a></td>
<td class = "home"><a href="{{site.baseurl}}/outline"><nav>About</nav></a></td>
<td class = "home"><button id = "logOut">Log out</button></td>
</tr>
</table>
<script>
let logOut = document.getElementById("logOut")
logOut.onclick = function exit() {
localStorage.setItem("userLoggedIn", "false");
localStorage.setItem("userid", "null");
document.getElementById("navigation").style.visibility = "hidden";
document.getElementById("lognav").style.visibility = "visible";
window.location.href = "{{site.baseurl}}/";
}
</script>
<!--
_layouts/default.html
customization to original Midnight theme
found through GitHub Pages Themes
-->
<html lang="{{ site.lang | default: "en-US" }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="https://kit.fontawesome.com/46e3c2907d.js" crossorigin="anonymous"></script>
{% seo %}
<link rel="stylesheet" href="{{ '/assets/css/style.css?v=' | append: site.github.build_revision | relative_url }}">
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<script src="{{ '/assets/js/respond.js' | relative_url }}"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!--[if lt IE 8]>
<link rel="stylesheet" href="{{ '/assets/css/ie.css' | relative_url }}">
<![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
{% include head-custom.html %}
</head>
<body>
<div class="wrapper">
<section>
<!-- nighthawk coding society has altered arrangement and inserted navigation that is updated in independent file -->
<div id="title">
<h1><a href="https://github.com/sreejagangapuram/Code-Crunch">Code Crunch<a></h1>
<p>Beat the clock, think fast, score high. Match the logos to score a point most points get the highest score on the leaderboard.</p>
{% include home.html %}
{% include lognav.html %}
</div>
<!-- this is Jekyll magic, each md file in site will be inserted here -->
{{ content }}
</section>
</div>
<script>
window.onload = function() {
let userLoggedIn = localStorage.getItem("userLoggedIn");
let userid = localStorage.getItem("userid");
console.log(userid)
if (userLoggedIn === "true") {
document.getElementById("navigation").style.visibility = "visible";
document.getElementById("lognav").style.visibility = "hidden";
} else {
document.getElementById("navigation").style.visibility = "hidden";
document.getElementById("lognav").style.visibility = "visible";
}
}
</script>
</body>
</html>
""" database dependencies to support sqliteDB examples """
from random import randrange
from datetime import date
import os, base64
import json
from __init__ import app, db
from sqlalchemy.exc import IntegrityError
from werkzeug.security import generate_password_hash, check_password_hash
''' Tutorial: https://www.sqlalchemy.org/library.html#tutorials, try to get into Python shell and follow along '''
# Define the User class to manpassword actions in the 'users' table
# -- Object Relational Mapping (ORM) is the key concept of SQLAlchemy
# -- a.) db.Model is like an inner layer of the onion in ORM
# -- b.) User represents data we want to store, something that is built on db.Model
# -- c.) SQLAlchemy ORM is layer on top of SQLAlchemy Core, then SQLAlchemy engine, SQL
class User(db.Model):
__tablename__ = 'users1' # table name is plural, class name is singular
# Define the User schema with "vars" from object
id = db.Column(db.Integer, primary_key=True)
_username = db.Column(db.String(255), unique=True, nullable=False)
_email = db.Column(db.String(255), unique=True, nullable=False)
_password = db.Column(db.String(255), unique=False, nullable=False)
# constructor of a User object, initializes the instance variables within object (self)
def __init__(self, username="Sreeja", email="sreeja@gmail.com", password="123sreeja"):
# variables with self prefix become part of the object,
self._username = username
self._email= email
self._password = password
# a getter method, extracts email from object
@property
def username(self):
return self._username
# a setter function, allows name to be updated after initial object creation
@username.setter
def username(self, username):
self._username = username
# a getter method, extracts email from object
@property
def email(self):
return self._email
# a setter function, allows name to be updated after initial object creation
@email.setter
def email(self, email):
self._email = email
# a getter method, extracts email from object
@property
def password(self):
return self._password
# a setter function, allows name to be updated after initial object creation
@password.setter
def password(self, password):
self._password = password
# output content using str(object) in human readable form, uses getter
# output content using json dumps, this is ready for API response
def __str__(self):
return json.dumps(self.read())
# CRUD create/add a new record to the table
# returns self or None on error
def create(self):
try:
# creates a person object from User(db.Model) class, passes initializers
db.session.add(self) # add prepares to persist person object to Users table
db.session.commit() # SqlAlchemy "unit of work pattern" requires a manual commit
return self
except IntegrityError:
db.session.remove()
return None
# CRUD read converts self to dictionary
# returns dictionary
def read(self):
return {
"username": self.username,
"email": self.email,
"password": self.password,
}
# CRUD update: updates user name, password, phone
# returns self
def update(self, username="", email="",password=""):
"""only updates values with length"""
if len(username) > 0:
self.username = username
if len(email) > 0:
self.email = email
if len(password) > 0:
self.password(password)
db.session.commit()
return self
# CRUD delete: remove self
# None
def delete(self):
db.session.delete(self)
db.session.commit()
return None
"""Database Creation and Testing """
# Builds working data for testing
def initUsers():
with app.app_context():
"""Create database and tables"""
db.create_all()
"""Tester data for table"""
u1 = User(username='sreeja', email="sreeja@gmail.com", password='123sreeja')
u2 = User(username='ekam', email="ekam@gmail.com", password='123ekam')
u3 = User(username='tirth', email="tirth@gmail.com", password='123tirth')
u4 = User(username='mani', email="mani@gmail.com", password='123mani')
u5 = User(username='user', email="user@gmail.com", password='123user')
users = [u1, u2, u3, u4, u5]
"""Builds sample user/note(s) data"""
for user in users:
try:
user.create()
except IntegrityError:
'''fails with bad or duplicate data'''
db.session.remove()
print(f"Records exist, duplicate email, or error: {user.username}")