Fatfile

This file contains the contents of every page in the wiki in no order whatsoever.

Consulting

Can I give you consulting math 101? You may already know this, and if so, forgive me.

  • Decide how much you want to make. Let's use a nice round number. USD$100,000 (Not saying this is your number, yours may be USD$250,000, or whatever. This is just an example.)
  • Remember to add health insurance, business insurance, error & omission insurance, taxes and fees and everything else. (Call an insurance broker, techinsurance.com, etc.)
  • Let's call this compiled number USD$150,000. (again, just an example.)
  • Double it. USD$300,000. You can expect no more than 50% utilization, and you have to spend time finding the next client/gig/opportunity. So you will only make half a years worth of hourly salary.
  • Convert to hourly. There are 2080 working hours in a year. So you can have a vacation, call it 2000. Divide 300,000 by 2,000. That's 150. So your hourly rate is $150/hour.
  • If you are 50% utilized, you will make USD$150,000 per year. With six months of time to find work, have a vacation, keep your certs alive, and expand your skill set.

References

Last modified: 202107100120

Glue Work

[0:10:32] Glue work is the meta work that helps keep the organization running and on track. e.g. scrum master stuff; fixing problems, increasing fluidity in between teams, creating coding standards for ease of production, etc.

[0:12:12] If you are only doing glue work and not your actual job, it may be beneficial but it is hurting your own career and potentially your ability to keep your job or get promoted.

[0:14:31] What do you want to get better at? Do more of that and get better at it. Find something that you will be happy and proud to do. When we start at a job, we are bad and then get better.

[0:18:30] Since certain fields just assume if you left a certain job you lost all of those skills, which of those doors are you willing to close to open some others?

[0:19:43] Have the career conversation with the boss about "when will I be promoted", "What do I need to do to do so", etc. Write them down for later.

[0:20:17] If you find yourself doing a whole lot of X, get a title that shows that you do X a lot.

[0:21:23] Create a story that shows that "because of the work X I did, Y was able to happen. It happened because of the work I did."

[0:22:22] If your colleagues, managers, etc. do not care about the glue work you are doing, stop doing it and only do what is on your job description. If your goal is to get promoted, a raise, etc. and what you need to get those promotions is not being done, focus only on your job description and achieving those goals until that goal is achieved. Push away requests that are not your problem. [0:23:20] Do not catch things that are about to drop. Do not try and fix what is broken. It is not your problem if they are not willing to reward you for your work.

[0:24:07] How are you spending your finite work hours? If it is not on the things that are bringing you towards your goals, be it happiness, a promotion, or whatever, do not do those things. Focus only on what you need. [0:24:46] You will only learn what you spend time on, so learn deliberately and spend time on the things that will reward you most. [0:25:26] Be public about learning and let people know what you've been working on. [0:26:02] Don't take learning opportunities from others if you know how; give them the work that will help them learn.

[0:26:25] "You should do X because you are so good at it." "Yes I am good at whatever I spend a lot of time on, you should see me doing Y."

References

  1. https://www.youtube.com/watch?v=KClAPipnKqw

Backlinks:

Last modified: 202107021505

Problem Solving

Solving big problems is just solving problems

Solving problems is the ability to break problems into smaller problems. Even if you don't instantly know how to solve it, and say "well, I'm probably going to need to do X and then Y", and can repeat that process for those sub-problems until you either know how to solve it, look it up, or ask someone.

Aptitude is more important than knowledge

The common thing to confuse "aptitude" with is "knowledge". I also talk about this when discussing interviewing with colleagues: many interviews check for "knowledge" (what does this function do? what is a hash? what does "CSS" stand for?) because it's easy to do and (presumably) because people mistakenly consider it a good heuristic for whatever makes someone a good developer. However, in general, "knowledge" is easy to get - go read wikipedia or a book or some documentation and memorize it. It's also not very useful - if you don't know something, go look it up! It helps because it makes you faster (not having to look everything up is why CPUs have instruction caches), and it might more quickly lead you toward a better solution (if you know several approaches already, you can more quickly consider which would be best), but much more important is "aptitude". It's much harder to teach someone how to think.

References

  1. https://www.reddit.com/r/adventofcode/comments/7kd8jt/what_would_you_say_are_the_minimal_skills_for/dre0uu3/

Last modified: 202107021453

git

Commits

  • Add files you want to commit: git add {file or folder name} or git add . (you don't want to add all unless you are POSITIVE it doesn't contain cruft or unwanted changes, use the --patch flag insteadl)
  • Add only portions of a file as 'hunks': git add --patch/-p {file or folder name} (file or folder is optional). This will prompt you with options:
    • y - stage this hunk
    • n - do not stage this hunk
    • q - quit; do not stage this hunk or any of the remaining ones
    • a - stage this hunk and all later hunks in the file
    • d - do not stage this hunk or any of the later hunks in the file
    • g - select a hunk to go to
    • / - search for a hunk matching the given regex
    • j - leave this hunk undecided, see next undecided hunk
    • J - leave this hunk undecided, see next hunk
    • k - leave this hunk undecided, see previous undecided hunk
    • K - leave this hunk undecided, see previous hunk
    • s - split the current hunk into smaller hunks
    • e - manually edit the current hunk (particularly if your code is really close together but needs to be broken down)
    • ? - print help

Case Sensitivity

Git by default is not case sensitive when it comes to filenames and will ignore renaming of file structures that are only by case. To change this default behavior, use git config core.ignorecase false. Note that setting this option to false on a case-insensitive file system is generally a bad idea. Doing so will lead to weird errors. For example, renaming a file in a way that only changes letter case will cause git to report spurious conflicts or create duplicate files.

If it is a file or files, you can change their name as normal and then within git via this command: git mv -f filename.txt Filename.txt. This will make it show up in your commit. If it is a directory, you will need to do this with every file within the directory.

Branches

  • See all branches: git branch
  • See the remote branches your local repo knows: git branch -a
  • Checkout an existing branch: git checkout {name}
  • Create and name a new branch: git branch {name}
  • Create and checkout a new branch: git checkout -b {name}
  • Create an orphaned branch: git checkout --orphan {branch_name}
  • Push the current branch: git push origin HEAD
  • Rename a branch. Assuming you're currently on the branch you want to rename: git branch -m {name}
  • Merge a branch (source) into another branch (destination):
    • Commit all changes in source branch
    • Checkout destination branch
    • git merge {source-branch}
  • Delete a fully pushed and merged branch: git branch -d {name}
  • Force delete a local branch: git branch -D {name}

Orphan Branches

Commits usually have one parent, their previous iteration. The root commit (very beginning) of your repo has none, and when you merge commit a fork with another branch or the master branch.

An orphan branch is a new root commit, where:

The first commit made on this new branch will have no parents, and it will be the root of a new history, totally disconnected from all the other branches and commits. In other words, it creates a new root commit and uses it as a starting point for your new branch.

Delete All Merged Branches

To delete all branches that have been merged, start out by pulling from remote to ensure you are using the most up to date info. Then check which branches are merged by running git branch --merged. We will be using egrep to grab these and put them into a macro that will delete each merged branch that doesn't fit within the regex. To ensure a branch that contains a certain keyword does not get deleted, add it to the egrep -v "(^...)" line, with each keyword separated by an OR |.

git branch --merged | egrep -v "(^\*|master|main|dev|staging)" | xargs git branch -d

Cherry Pick

When should I use cherry-pick? The short answer is: as rarely as possible.

Cherry picking

Revert

A revert allows you to go back to a previous commit, reversing those previous between commit X (HEAD) and commit Y(the selected commit). This will create a reversal commit for each commit to be undone between X and Y. In the case of a single commit to be undone, it will make a single reversal commit.

To revert one or many commits, open your git log and find the commit you want to revert back to. Save this hash.

The -m flag is used to revert a merge; to set where the mainline is, which parent you are wanting to revert back to. Most of the time it is 1.

$ git revert [-m 1] <commit-hash>

Stashing

Stashing allows you to temporarily save changes without committing anything.

To stash some changes, use git stash save 'message about stash', or just git stash if you want to leave out the message.

To see what you have stashed, use git stash list to see all stashed code. Then see what is in each stash by using git stash show {index}, and you can see it diffed by using the -p flag.

Stashes can be listed recalled via the indexes shown: git stash apply {index} or git stash pop {index} if you want to remove it from the stashes after being applied.

You can git stash drop {index} individual stashes or git stash clear the entire stash.

Git Aliases

Flags

  • --global will set the alias across your whole machine
  • --unset will unset the following alias
  • --unset-all will unset all of the aliases found at the following alias
shell> git config --global alias.co checkout # now 'git co' is aliased to 'git checkout'
shell> git config alias.p 'push origin HEAD'  # now 'git p' is aliased to 'git push origin HEAD' ONLY for current project
shell> git config --global --unset alias.p # now 'git p' is no longer aliased

Gitignore

Creating a .gitignore file in the root folder of your project will ensure every file that matches a line within the file will be ignored by git.

  • Using a * will work as a wildcard for every file within that level of the given directory, or as a wildcard within a filename.
  • Using two ** in the filepath will look within every level recursively from that point forward. e.g. **/.DS_Store will find a file called .DS_Store in the root directory as well as any others in any folders within that root directory. lib/**/__pycache__ will match any files or folders named __pycache__ that are within the lib directory at any depth.

Global gitignore

You can ignore files globally by adding them to ~/.gitignore_global.

Delete previous files in gitignore

If you add a file to .gitignore after previously committing that file, you may see untracked changes on those files. You have to remove the old files from the git repository to remove that error.

  • Remove the existing files: find . -name {filename} -print0 | xargs -0 git rm -f --ignore-unmatch
  • Add the file to the gitignore: {filename}

Credentials

If you receive a message like this when trying to push up to your repo:

remote: HTTP Basic: Access denied
fatal: Authentication failed for 'https://gitlab.com/myusername/repo.git'

or

remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/milofultz/tod.git/'

Then you may have revoked or renewed your token and need to reset it. To do so, type this in the terminal:

$ git credential reject

And when you receive a new line, enter in url= followed by the url that showed up previously in the error message. Then use ctrl-c or ctrl-d to quit.

url=https://github.com/milofultz/tod.git/

On trying to push again, you will get prompted for authentication and it will work.

Errors

CRLF => LF: https://stackoverflow.com/questions/20168639/git-commit-get-fatal-error-fatal-crlf-would-be-replaced-by-lf-in/31144141#31144141

Meta

Use VIM as Editor

  • Install Vim using homebrew
  • Set vim to be the default editor with git config --global core.editor "vim"

Good Commit Hygiene

References

  1. https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging
  2. https://koukia.ca/delete-a-local-and-a-remote-git-branch-61df0b10d323
  3. https://bugfactory.io/blog/orphaned-brachnes-in-git/
  4. https://git-scm.com/docs/git-add
  5. https://devconnected.com/how-to-cherry-pick-git-commits/
  6. https://phoenixnap.com/kb/git-revert-last-commit
  7. https://stackoverflow.com/questions/41842149/error-commit-is-a-merge-but-no-m-option-was-given
  8. https://superuser.com/questions/1309196/how-to-update-authentication-token-for-a-git-remote
  9. https://www.git-tower.com/learn/git/faq/cherry-pick/
  10. https://stackoverflow.com/questions/17683458/how-do-i-commit-case-sensitive-only-filename-changes-in-git

Backlinks:

Last modified: 202108031658

Making a Good README

Your README file contains a high level overview for people interested in using, contributing, or perusing your code.

Structure/Content

  • Title
  • Overview - A brief description outlining what the project
  • Table of Contents - You can link to the different sections below using # followed by the lowercased and kebab-cased version of the header. e.g. Table of Contents => #table-of-contents
  • Description - A more detailed outline of the project. What does it do? Is there a high level list of features? If describing a project that has visual features, consider adding pictures or animations of the features and functionality in this section.
  • Installation - How can another developer get your project up and running on their own? What dependencies are required? Are there environmental requirements? Be specific, and outline steps to take in order to get the project running.
  • Usage - Further details on how the project is meant to be used may be helpful. For a library or framework, this section would outline how to use the library within another project. For a service that is meant to be used within a larger project architecture, instructions on how to integrate may be necessary.

Additionally, for some projects, additional information might make sense.

  • Related Projects - Links to other repositories that are related to the current one. Are there partner projects? Is there a newer version of this project elsewhere?
  • Team Members - Add the names of your team members. Describe roles on the team such as "Product Owner", "Scrum Master" and more.
  • Contributing - If you'd like others to be able to contribute to your work, outline a process through which they can submit a request for changes to be incorporated. More specifically, outline the Git workflow for these contributors. Should they use a feature branching workflow? Should they rebase or merge? Should the fork the repository? What is the review process?
  • Roadmap - What future enhancements are planned? What is the current status of the project? Is it being actively maintained?
  • License - If open source, state how the project is licensed.

Last modified: 202107020454

Applescript

Applescript is a programming language used to create scripts in Mac computers.

Variables

set variableName to value

Destructure a list to new variables

set newList to {100, 200, 300}
set { x, y, z } to newList # x=100, y=200, z=300
set a to item 2 of newList # a=200

Have Application Do Something

tell application "iTerm" to \# put actions here

tell application "iTerm"
  \# put actions here
end tell

Actions

  • activate - Run program
  • open "Macintosh HD:Users:username:..." - Open file at filepath
  • close window 1 - Close window
  • set size of front window to {640, 400} - Set window size (x, y)
  • set position of front window to {0, 0} - Set window position (x, y)
  • set bounds of front window to {300, 30, 1200, 900} - Set window size and position {X-start, Y-start, X-end, Y-end}; corresponds directly to pixels of display resolution

Comments

-- This is a single line comment
\# This is another single line comment
(* This is
   a multi
   line comment *)

References

  1. http://downloads.techbarrack.com/books/programming/AppleScript/website/files_&_folders/opening_files.html
  2. Error Messages

Last modified: 202107020557

Best Practices (Programming)

Writing Code

  • Programming isn't about the stack or the systems architecture; the arch meta will change faster than you can learn it.
  • The number of frontend Frameworks out there are N+1.
  • DRY, recursive funcs, polymorphism are [typically] afterthoughts and should not be a goal while you're developing the solution.
  • TAKE TIME OFF. If you have 24 hrs time off that's three days office time. TAKE. THEM. AND. GO. AFK. It's best to plan the time and let your team know. Try to make it non-work related (but not self-destructive): camping, reading, visit family, practice hobbies, volunteering with animal shelters, study fine art, date people .... Make memories. Please, just live your life.
  • Understand what good testing means. If you have trouble with this, look at tests on github of frameworks/languages. The basic form of tests come in the following for Javascript for front/back end devs (Node.js specific?): Unit Tests, Integration Tests, End-to-end tests. Understand why they're utilized and how to leverage them for various use-cases.
  • Read the documentation. It's your job to understand what's going on internally for your stack's framework(s) and if it takes you a few days to estimate the work-cost of utilizing a new lib reading docs is time well spent. If management doesn't understand this time after time then look for a new place to work.
  • Buy you a whiteboard. Plan your work on it - sprints, logic, component relationships, cat drawings. (and of course it doesn't have to be a whiteboard, but the open space of a whiteboard to track my weekly meetings, logic intuitions, etc. all are best expressed for me in a large space)
  • Keep a journal if you can (or a blog/vlog/written notes if that's the way you track your thoughts). Reflecting on the way I thought about a problem or feature set has been the best way for me to recognize my growth. (e.g. In college we never really discussed the implications of "Immutability" though it was mentioned and I found that as I kept journaling my understandings of Immutability with the context of the problems at hand it helped to give me a portrait of how/when to utilize it for future projects more effectively.)
  • "Make it correct, make it clear, make it concise, make it fast. In that order." - Wes Dyer
  • "Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, Structure and Interpretation of Computer Programs

Job/Soft Skills

  • The job of a programmer on a team is to communicate. You will not get a better application from all-nighters, you will not 'free solo' an application. All systems are the sum total of the discussions, joint planning, and hard work. Any product you concoct alone, devoid of communication, will fail in a team-based env. (though, shared all-nighters in a team session have been some of the best moments in my career, so take this one with a pinch of salt)
  • Few tho they are, programming "rock stars" exist: you will see them on NPM and may even work beside them or read their blog posts, but these are outliers. (Read "Outliers" by Malcom Gladwell for better context than I can provide). I had the opportunity of working with an "Outlier" and though my understanding of programing appreciated from that time, the codebase suffered (and still suffers) from it.
  • Kanban's will keep your team in check. Stay on top of your tracking especially if your portion is behind; it's not a mechanism of doubt or shame or illness or anything that contributed to you being behind on work. Your honesty is tantamount: when your peers start to doubt your abilities you're already in a bigger hole than you probably are. Learn to communicate the nature of your issues with the problem at hand and I guarantee that your peers will recognize it if not in whole than in part. Speak up!
  • Tell your boss to have patience. But first, learn how to tell your boss to have patience.
  • Sprint estimations for new features are, in the practical sense, a fallacy. Feature-sprints are pretty loose unless you work with a team that's one-out-of-a-thousand. Pad your dates by a factor of 2 where you can. (2 months = 4 months, etc. - also depends on your team size.)
  • If your team consistently underestimates the time needed for a patch/feature (sprints) after 1.5/1.75 yrs time consider leaving unless you (or management) can really commit to change in this regard.
  • "Glue Work." In the scope of dev, there are no enemies. Not your boss's boss, not your boss, not your team members, not your clients, not you. Company culture is usually your first culprit if things go wrong, and if you can't vocalize why/how then it requires one of two things: a contractor to debug your company culture OR for you to leave; there is (in my experience) no middle ground here. (Unless it's your job to fix it, at least learn how to recognize Glue Work: https://www.youtube.com/watch?v=KClAPipnKqw)
  • If you work for a non profit, make sure your worldview is in line with the org's mission statement and that those you work with harbor your own sentiments. If not, leave.
  • Do not interview for new jobs with/on company property or during work hours. Even if you have consent to do so, just don't. Wait until lunch, wait until you're home to compose your email resp to an offer. Cover your bases legally especially in the realm of startups.
  • When looking for jobs, ask about their testing practices. If they don't really answer, obfuscate their response, or just dont have an answer, avoid them at all costs. Tests/testing are a symptom of a healthy company culture.
  • Learn/Practice vocalizing thoughts such as "I think you're wrong, here's why..." and "I don't think that's right given ..." and "While that's part of the problem an equally (if not more) pressing issue is ..." It's important to learn how to vocalize your misgivings, even if you're not 100% confident about them; your intuitions about a given problem will usually find similar minds on the team chip-in and fill the gaps.
  • Empathy. Empathy for your co-workers, empathy for your clients, empathy for your past-self too. Practice empathy.

Self Development

  • Make a habit of reading books if not directly related to dev then tangentially related. (4 books per year was a good pace for me.)

References

  1. https://www.reddit.com/r/webdev/comments/kzqmhb/im_in_awe_of_you_all/
  2. https://softwareengineering.stackexchange.com/questions/43151/should-you-sacrifice-code-readability-with-how-efficient-code-is

Last modified: 202107051709

XML

There's currently nothing here.

Backlinks:

Last modified:

SVG

SVG's are scalable vector graphics. They consist of instructions for the computer to follow to create the drawing.

An SVG file is an XML markup file and thus is super simple to create yourself. All SVG's start out with an outer svg element.

<svg version="1.1" width="300" height="200" viewBox="x1 y1 x2 y2" xmlns="http://www.w3.org/2000/svg">
  <!-- Version is not necessary -->
  <!-- W/H set during render, can be overwritten via CSS -->
  <!-- Viewbox is the part of grid to be shown  -->
  <!-- xmlns is required only for SVG files, not inline HTML -->
</svg>

Drawing Shapes and Paths

SVG's use a grid system, where positive X is right and positive Y is down. The top left of the document is then 0, 0.

By default, renderings that come first, are placed below renderings that come later.

<svg ...>
  <rect ...></rect>      // Behind the circle
  <circle ...></circle>  // On top of the rect
</svg>

You can group SVG elements in a <g> container, and all transformations made on the container will occur to their children.

Path

The path element is how you "pick up" and "put down" your "pen", as well as draw the lines which can make up a filled shape or just a stroked line. The directions go within the d attribute.

M x y is when you place your pen a given position without a stroke. L x yis when you draw a line to (x,y) from your starting point.

<!-- This will move the pen to (0, 10) and draw a line to (10, 0) in the given box -->
<path d="M 0 10 L 10 0"></path>

Shapes

Rectangles are drawn with the rect element.

Circles are drawn with the circle element, with a center X/Y and a radius.

<circle cx="50" cy="50" r="50"/>

Other polygons are drawn with the polygon element and a series of X,Y points separated by spaces.

<polygon points="0,100 50,25 50,75 100,0" />

External file or inline HTML?

External files allow the computer to only have to load the data once and then reuse it throughout the page. If you have it written out multiple times, that is a lot of extra work.

References

  1. https://stackoverflow.com/questions/18467982/are-svg-parameters-such-as-xmlns-and-version-needed
  2. https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Positions
  3. https://developer.mozilla.org/en-US/docs/Web/SVG/Element
  4. https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths
  5. https://developer.mozilla.org/en-US/docs/Web/SVG/Element/circle
  6. https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polygon

Last modified: 202107020546

Javascript

There's currently nothing here.

Backlinks:

Last modified:

Regular Expressions

Regular Expressions or "regex" is used to describe a series of characters. If it has a pattern in its formatting, regex can be used.

Regular Expression Syntax

This syntax is for Javascript, but it is mostly what I have used in everything so far.

Metacharacters

  • ^ at the beginning means that the match must start with what follows.
  • $ at the end means that the match must end with what precedes it.
  • . means any character that is in that place is allowed. e.g. /h.llo/ will return a match on "hello", "hallo", "hullo", etc.
  • * means match the preceding character or group 0 or more times.
  • + means match the preceding character or group 1 or more times.
  • ? means the preceding character is optional in the match. (e.g. /gre?a?y/ matches 'grey', 'gray', and 'gry')
  • +? means match as few instances of the preceding character or group as possible.
  • x|y means x or y.
  • \ is used to escape characters.
  • [abc] means one of the characters within the brackets ('a' 'b' or 'c') must be present at that position. This can include one or more ranges of characters, which are notated with a hyphen (e.g. 'a-z', 'A-Z', '0-9'). Adding a ^ within the brackets means anything but what is inside.
  • x{n} returns a match if a x is found n number of times. n can be a range separated by a comma (e.g. {2,4}). A single comma and nothing succeeding it means at least n times (e.g. {2,} means at least 2 times).
  • () indicate that whatever is within them should be grouped together, in instances of curly braces for instance.

Shorthand Character Classes

  • \w is any alphanumeric char or underscore.
  • \W is anything but an alphanumeric char or underscore.
  • \d is any digit.
  • \D is anything but a digit.
  • \s is any whitespace character.
  • \S is any non-whitespace character.
  • \b denotes a word boundary. Placed after a string of chars, it matches if the string is found and is succeeded by anything but an alphanum or underscore.

Lookahead and Lookbehind

Lookahead and lookbehind allow search queries that will not be included in the final match. e.g. x(?=y) will return x only if succeeded by y.

Lookahead

  • x(?=y) will match x only if it is followed by y.
  • x(?!y) will match x only if it is not followed by y.

Lookbehind

  • (?<=y)x will match x only if it is preceded by y.
  • (?<!y)x will match x only if it is not preceded by y.

Flags/Suffixes

  • i means the preceding search is case insensitive. If i is absent, it is case sensitive.
  • g means it will search for all instances, not just the first one it finds.
  • m means multiline search

Backreferences

\1, where 1 is any incremental number, is called a backreference. The number is referring to the capture group of the current reg ex. When called, the regex will search for the exact instance found of that regex.

For example, /[A-Z][0-9]\1/ will search for any char between A-Z, 0-9, and whatever character was found in the first character group. If you were searching through 'A9A' it would be a success, while 'A9B' would fail. This is because capture group 1 found an 'A', and therefore the backreference (\1) must also find an 'A'.

Common Regex Queries

Regex Matches
[\s\S] Anything
[^\n\r] Anything except for a newline
[A-Za-z0-9] Alphanumeric characters
[A-Za-z] Alphabetic characters
[0-9] or \d Numeric characters
[\.,-\/#!$%\^&\*;:{}=\-_`~()@\+\?><\[\]\+] All punctuation (non alphanum graphic characters)

References:

  1. https://regular-expressions.mobi/backref.html?wlr=1
  2. https://regexr.com/
  3. https://regexcrossword.com/

Backlinks:

Last modified: 202107020456

Job Interviews

What are you trying to get from this position? What do they want from you in taking this position?

Questions to Ask

  • Of the people you know doing this job, what is that person like, and what are they doing in that position?
  • What is a typical day?
  • What is the work environment and company culture like?
  • What are the goals for the company? Short term and long term
  • How would performance be measured?
  • What are the company policies for learning and development?

Last modified: 202107021455

Express

Express is a Javascript-based server application that will help route requests from the client.

Getting Started

First, start your project with npm init in the project folder. Then npm i express. Now you can start implementing the barebones in your project.

// app.js
const express = require('express');
const app = express();
const port = 3000;

app.listen(port, () => console.log(`Listening on port ${port}`));

To get it running, set up your package.json with a script to run. You can also use nodemon to run and restart upon file changes.

"scripts": {
  "start": "node app.js",
  "dev": "nodemon app.js"
}

Upon running one of these scripts (npm run start/dev), you should see a message in your terminal that your app is listening on port 3000.

Routes

// Parameters: `route`, and `callback` when request and response objects are received and created 
app.get('/', (req, res) => {
  data = 'We did it!';
  res.send(data);
});

Upon completing this and restarting your server, you should be able to go to localhost:3000 and see "We did it!" in your browser window.

Query Parameters

You can access the query parameters via the req.query object.

// .../products?example=1?another=five
app.get('/products', (req, res) => {
  const example = req.query.example;
  const another = req.query.another;
  res.send(JSON.stringify([example, another]));
});

References

  1. http://expressjs.com/en/starter/installing.html
  2. https://stackoverflow.com/questions/17007997/how-to-access-the-get-parameters-after-in-express

Backlinks:

Last modified: 202107172004

React

React is a Javascript framework for implementing dynamic single page applications into your site.

Setting Up

Use create-react-app with npm or build it from scratch.

Components

Components are reusable pieces of JSX that can be used to dynamically render HTML. The JSX is written as is, outside of any quotes. When components are referenced, they are written with the closing /. Components are named in PascalCase.

Note the parentheses used in the arrow function instead of curly braces. This is because the implicit return will enclose everything within the parentheses and allow it to be placed on multiple lines.

const FoodItem = () => (
  <li>Get some of this food!</li>
);

const GroceryList = () => (
  <ul>
    <FoodItem />
    <FoodItem />
  </ul>
);

These are rendered via the render method of the ReactDOM, which takes the component followed by the destination it will be appended to. Most common is that you will have a single div that your whole website will be injected into, i.e. <div class="app"></div>.

ReactDOM.render(<GroceryList />, document.getElementById('main'));
<!-- output in associated HTML file -->

<div id="main">
  <ul>
    <li>Get some of this food!</li>
    <li>Get some of this food!</li>
  </ul>
</div>

Component Properties, or Props

Properties are attributes that can be passed into and used to populate parts of that component. Props are always passed in as an object of keys that correspond to the attributes given on the JSX element. e.g. <Component name={"John"} age={6} /> will pass { name: "John", age: 6 } into the Component. Props are surrounded by curly braces when they are assigned and when they are recalled. Inside the curly braces, valid Javascript may be called.

const GroceryListItem = (props) => (
  <li>{props.item.toUpperCase()}</li>
);

const GroceryList = (props) => (
  <ul>
    {props.groceryItems.map(propItem => <GroceryListItem item={propItem} />)}
  </ul>
);

ReactDOM.render(
  <GroceryList groceryItems={['candy', 'cookies', 'ice cream']} />, 
  document.getElementById('app')
);
<!-- output in associated HTML file -->

<div id="app">
  <ul>
    <li>CANDY</li>
    <li>COOKIES</li>
    <li>ICE CREAM</li>
  </ul>
</div>

Default Props

const GroceryListItem = (props) => (
  <li>{props.item.toUpperCase()}</li>
);

GroceryListItem.defaultProps = {
  item: 'Milk',
};

const GroceryList = (props) => (
  <ul>
    <GroceryListItem />
  </ul>
);

ReactDOM.render(<GroceryList />, document.getElementById('app'));
<!-- output in associated HTML -->

<div id="app">
  <ul>
    <li>MILK</li>
  </ul>
</div>

PropTypes

You can add type checking to your props to make your code a bit more robust. If the types you entered don't match the element's type, then it will only give a warning in the console and will still render (as long as it is able).

Primitive types in PropTypes:

  • array
  • bool
  • func
  • number
  • object
  • string
  • symbol

You can also specify .isRequired at the end of your propType definition.

import PropTypes from 'prop-types';

const GroceryListItem = (props) => (
  <li>{props.item.toUpperCase()}</li>
);

GroceryListItem.propTypes = {
  item: PropTypes.string.isRequired;
};

Exporting Components

You can put the component into another file and import it in by using the export default componentName syntax.

// GroceryListItem.js
const GroceryListItem = (props) => (
  <li>{props.item.toUpperCase()}</li>
);

export default GroceryListItem;
// app.js
import ...
import GroceryListItem from './GroceryListItem.js';

ReactDOM.render(
  <GroceryListItem item="candy" />, 
  document.getElementById('app')
);

Higher Order Components

Higher order components are just higher order functions in React, in that they are functions that spit out another function based on what is input. One example is a React HOC that takes in a component and adds logging capabilities to it. Since it is wrapping the entire element

import ...

const TrackingWrapper = ({ WrappedComponent }) => {
  return class extends React.Component {
    constructor(props) {
      super(props);
    }

    logInteraction(event) => {
      const logObject = {
        timstamp: Date.now(), 
        element: event.target
      };
      console.log(logObject);
      // POST to server
    }

  render() {
    return (
      <div className="tracking-wrapper" onClick={this.logInteraction}>
        {/* This will pass in all props passed to the WrappedComponent in their given namespace */}
        {/* Equivalent to the spread operator on a function definition */}
        <WrappedComponent {...this.props} />
      </div>
    )
  }
};

export default TrackingWrapper;

User Interaction/Event Listeners

Components can have local event listeners assigned directly to themselves.

const GroceryListItem = (props) => {
  const onListItemClick = function (e) {
    console.log("Yum!");
  };

  return (
    <li onClick={onListItemClick}>{props.item}</li>
  )
};

If you want to use an event listener on a class component that will be used within another this context, you need to be sure you maintain the correct this, either through bind, or the more sexy use of an anonymous arrow function.

// Good
return (
  <li onClick={this.onListItemClick.bind(this)}>{props.item}</li>
)

// Better
return (
  <li onClick={() => this.onListItemClick()}>{props.item}</li>
)

Stateless Functional vs. Class

All of the previous examples have used stateless functional components, which are declared at runtime and essentially become a static web page. If you want to have user interaction and a dynamic webpage, you will want to include state. State is just a dynamic memory for a given component, e.g. whether it has been clicked or has a given property. State is only included on class components and is initialized in the constructor.

First you will want to convert your stateless functional component into a class component.

class GroceryListItem extends React.Component {
  constructor (props) {
    super(props);
  }

  render () {
    return (
      <li>{this.props.item}</li>
    )
  }
};

Then you can add your state to the element via the class. When this.setState is called, the element rerenders in the DOM, applying whatever changes you have made to the state and control flow of the rendering of the element.

class GroceryListItem extends React.Component {
  constructor (props) {
    super(props);

    this.state = {
      hover: false,
    };
  };

  onClick () {
    this.setState({
      hover: !this.state.hover,
    });
  };

  render () {
    const style = {
      fontWeight: this.state.hover ? "bold" : "normal"
    };

    return (
      <li style={style} onClick={this.onClick.bind(this)}>{this.props.item}</li>
    );
  };
};

For the element to properly rerender, you must update the state by using the setState method. This will cause what React calls "reconciliation", which will update what needs to be updated in the DOM.

React Router

React Router is

References

  1. https://reactjs.org/docs/introducing-jsx.html
  2. http://jamesknelson.com/javascript-return-parenthesis/
  3. https://stackfan.com/loop-through-an-array-of-objects-in-react/
  4. https://css-tricks.com/understanding-react-setstate/
  5. https://reactjs.org/docs/typechecking-with-proptypes.html
  6. https://www.npmjs.com/package/prop-types

Backlinks:

Last modified: 202107081810

Model View Controller

This design pattern is used to separate functionality, logic, and component management. MVC can feel or seem confusing because there is not one way to do it, and many different frameworks that utilize MVC do it differently from one another.

Components

Model

The model is the brain of the application, responsible for getting and manipulating the data. It is often interacting with some kind of database or data in a file.

The model is often communicating with the controller, which is requesting data and/or updating the view. Sometimes the updating of the view is delegated to the model, sometimes to the controller.

View

This is what the user interacts with. In web development, this is usually made up of HTML and CSS.

The view is usually told what to show by the controller by being given dynamic values, usually with some kind of template engine, like Handlebars, ERV, HAML, Jinja2, etc.

Controller

The controller takes in user input and decides what to do with it. Usually the user interaction with the browser will go through some kind of router which will then give the controller a specific method to execute.

The controller acts as a middleman between the controller and the view. It takes the user input, passes it to the model which will then return some data to the controller, who then tells the view what to display to the user.

Example Frameworks Using MVC

  • Ruby on Rails
  • Sinatra
  • Laravel
  • Codeigniter
  • Zend
  • Express
  • Backbone
  • Angular
  • Django
  • Flask
  • React (view)

References:

  1. https://www.youtube.com/watch?v=pCvZtjoRq1I
  2. https://www.youtube.com/watch?v=DUg2SWWK18I

Last modified: 202107020452

Magic Numbers (Programming)

Magic numbers are numbers that have no semantic meaning within the program. These are problematic for maintenance and bug fixing since somebody reading the code later could have no idea what exactly the numbers represent.

/* BAD: Magic Numbers */
function calculateTotal(price) {
  return price + price * 0.09 + 2;
}

/* GOOD: Semantic Meaning! */
function calculateTotal(price) {
  const taxRate = 0.09;
  const serviceCharge = 2;
  const calculatedTax = price * 0.09;

  return price + calculatedTax + serviceCharge;
}

Backlinks:

Last modified: 202107080231

Accessibility

Checklist

Use this checklist to ensure you are doing your best to meet accessibility requirements.

Contrast

There needs to be a contrast of at LEAST 4.5:1 between the background and foreground of colors for readability.

"In WCAG 2, contrast is a measure of the difference in perceived "luminance" or brightness between two colors (the phrase "color contrast" is never used). This brightness difference is expressed as a ratio ranging from 1:1 (e.g. white on white) to 21:1 (e.g., black on a white)."

Examples

Bad

References

  1. https://webaim.org/resources/contrastchecker/
  2. https://webaim.org/articles/contrast/
  3. https://www.a11yproject.com/checklist/
  4. https://www.w3.org/WAI/test-evaluate/#tools

Backlinks:

Last modified: 202105310511

Test-Driven Development

In programming, test-driven development is when tests are developed first before the code is written.

In test-driven development the mantra has always been, red, green, refactor. Write a failing test and run it (red), make the test pass (green), then refactor it (that is look at the code and see if you can make it any better).[1]

  • You can’t write any production code until you have first written a failing unit test.
  • You can’t write more of a unit test than is sufficient to fail, and not compiling is failing.
  • You can’t write more production code than is sufficient to pass the currently failing unit test.

Best Practices

Write the test that forces you to write the code you already know you want to write.

Avoid the central behaviors as long as possible. Don't go for the gold right away.

Decouple the production code from the test code by ensuring your tests are not 1:1 for the class methods or functions. Create and refactor as you go in production, but allow the tests to remain.

Why Use TDD

  • Your code will ALWAYS be working just a second ago when you last tested.
  • It is double-entry bookkeeping for development.
  • A test suite that you don't trust is worthless. A test suite that does not allow you to make a decision when it passes is useless. There can be NO HOLES.

References

  1. https://github.com/gregmalcolm/python_koans
  2. Clean Code
  3. https://qualitycoding.org/3-laws-tdd/
  4. Examples of TDD in action

Last modified: 202105310500

VIM

There's currently nothing here.

Backlinks:

Last modified:

grep

grep finds string patterns within a given file or folder.

$ grep PATTERN dir/file.name
$ grep 'THIS THAT' dir/file.name

Regular Expressions

Square brackets do the same as normal, and also includes special POSIX groups, that do what you assume: [:alnum:], [:alpha:], [:blank:], [:cntrl:], [:digit:], [:graph:], [:lower:], [:print:], [:punct:], [:space:], [:upper:], and [:xdigit:].

Search with OR, AND, NOT

OR

$ grep 'PATTERN1\|PATTERN2' dir/file.name

AND

$ grep PATTERN1 dir/file.name | grep PATTERN2

NOT

$ grep -v 'NOTPATTERN' dir/file.name

Chain together a NOT with a regular search

$ grep 'THIS' dir/file.name | grep -v "NOT THIS'

Options

Options with a single hyphen can be combined and placed after grep. Double hyphen options are separated.

$ grep -rin PATTERN file.diz
  • -r: search recursively within a folder
  • -i: ignore case of search pattern
  • -n: print line number where pattern is found
  • -h: suppress filename from output
  • --color: color the output where pattern is found
  • --include=GLOB: search only files whose base name matches GLOB using wildcard matching (e.g. $ grep --include=*.md PATTERN)
  • --exclude-dir=dir_name or --exclude-dir={multiple,dir_names}

Output Formatting

You can use awk to print out a formatted output. -F and the following char is where in the string awk will split. Each split section can be called using $NF, with NF being the number of the field we want. $0 is everything.

grep IDEA | awk -F: '{print $1}'

References

  1. https://www.man7.org/linux/man-pages/man1/grep.1.html

Last modified: 202105310508

NPM

Node Package Manager helps with Node development in Javascript.

devDependencies

You can save packages as a devDependency by using --save-dev as an option in the CLI.

devDependencies are for the developers of the project. Things like test frameworks, documentation, etc. If someone downloads and uses your project, they won't have the dev dependencies installed. If someone wants to build on your project, they can download the dev dependencies.

Backlinks:

Last modified: 202107130109

terminal

There's currently nothing here.

Backlinks:

Last modified:

bash

Basic Functions

  • cp [-r] ./source ./destination - Copy file or directory [-r] from source to destination
  • mv [-r] ./source ./destination - Move/rename file or directory [-r] from source to destination

Background Tasks

You can run tasks in the background within a terminal window by placing an & at the end of the command you want running. You can see these background jobs with jobs and kill the job that you want with kill % followed by the index, or just kill % to kill all jobs.

Event Designators

An event designator is a reference to a command line entry in the history list. Unless the reference is absolute, events are relative to the current position in the history list.

  • $_ Repeat the last argument used, e.g. mkdir folder-name && cd "$_"
  • !! Repeats the previous command
  • !10 Repeat the 10th command from the history
  • !-2 Repeat the 2nd command (from the last) from the history
  • !string Repeat the command that starts with “string” from the history
  • !?string Repeat the command that contains the word “string” from the history
  • ^str1^str2^ Substitute str1 in the previous command with str2 and execute it
  • !!:$ Gets the last argument from the previous command.
  • !string:n Gets the nth argument from the command that starts with “string” from the history.
  • !^ first argument of the previous command
  • !$ last argument of the previous command
  • !* all arguments of the previous command
  • !:2 second argument of the previous command
  • !:2-3 second to third arguments of the previous command
  • !:2-$ second to last arguments of the previous command
  • !:2* second to last arguments of the previous command
  • !:2- second to next to last arguments of the previous command
  • !:0 the command itself

Aliases

WIthin your ~/.bashrc file, add this line and populate it how you need:

alias alias_name="command_to_run"

# e.g.
alias poo="say 'I have to poop really bad'"

When complete, run source ~/.bashrc or source ~/.zshrc and restart bash to have them take effect.

Pipe

To connect the STDOUT of one command to the STDIN of another use the | symbol, commonly known as a pipe.

# long way
$ thing1 > tempfile
$ thing2 < tempfile

# shorter
$ thing1 > tempfile && thing2 < tempfile

# shortest
$ thing1 | thing2

Base64

base64 path/to/file > output.txt will encode whatever file into base64.

echo -n 'some string' | base64 > output.txt will encode a string as input and not encode unusable chars, like line feeds.

The --decode flag may be added to reverse this process.

Troubleshooting

Errors from Windows

If you got a script that looks totally fine but is throwing errors that make very little to no sense, like failing cd and cp, it's probably containing \r from a Windows computer.

tr -d "\r" < oldname.sh > newname.sh

References

  1. https://www.serverlab.ca/tutorials/linux/administration-linux/how-to-base64-encode-and-decode-from-command-line/
  2. https://linuxize.com/post/how-to-create-bash-aliases/
  3. https://askubuntu.com/questions/172982/what-is-the-difference-between-redirection-and-pipe/172989#172989?newreg=cfc8024a2d4b40daa24578e47df2b7cf
  4. https://stackoverflow.com/a/11428439

Backlinks:

Last modified: 202107281718

NVM

Node Version Manager allows you to use multiple diferent versions of node and switch between them easily.

Installation

NVM

$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash

Be sure to completely restart your terminal before proceeding.

Node

$ nvm install --lts # most recent version with long term support
$ nvm install node  # most recent version without LTS

Usage

$ nvm use --lts
$ nvm use node

Specific Versions

$ nvm ls                # show all installed versions
$ nvm install xx.xx.x   # x's meaning the version numbers
$ nvm use xx.xx.x
$ nvm uninstall xx.xx.x

Set Default Node Version

$ nvm alias default xx.xx

References

  1. https://techstacker.com/run-multiple-node-versions-node-nvm/

Last modified: 202107021741

Collections (Python)

These are some resources on how to use the collections Python package.

defaultdict(type)

from collections import defaultdict

counter = defaultdict(int)
counter["sheep"] += 1
print(counter["sheep"])  # 1
print(counter["dog"])  # 0

Will allow builtin methods based on the default type. defaultdict(int) will allow a += 1 on any key and it will be defined immediately if doesn't exist; (set) will allow .add(value) to a set and will create it if none exists, etc.

deque

from collections import deque

cards = [1,2,3,4]
deck = deque(cards)

top_card = deck.popleft()
deck.append(top_card)

# cards == [2,3,4,1]

If you need a copy of the deque, you will need to import the copy.deepcopy method, as slices don't work. If you need to slice, you can use itertools.islice.

Note that if you are looking for a queue, you can use a standard list as a queue by using list.pop(0) and list.append(item). It is much faster and requires no imports.

References

  1. https://docs.python.org/3/library/collections.html

Last modified: 202107181935

Itertools (Python)

Resources on how to use the itertools Python package.

itertools.product()

Avoid using nested for loops to iterate through multiple different lists or numbers

for var1 in xrange(min1,max1,step1):
  for var2 in xrange(min2,max2,step2):
    ...
      ...
        ...
          for var6 in xrange(min6,max6,step6):
            '''
            Do something and be icky in the process due
            to being in the middle of six nested for loops
            '''
x1 = xrange(min1,max1,step1)
x2 = xrange(min2,max2,step2)
x3 = xrange(min3,max3,step3)
...
for v1, v2, v3, v4, v5, v6 in itertools.product(x1, x2, x3, x4, x5, x6):
  icky_thing(....)

References:

  1. https://stackoverflow.com/questions/11174745/avoiding-nested-for-loops

Last modified: 202107020541

Virtual Environments (Python)

Virtual environments allow you to develop in a clean slate, leaving nothing to global packages and allowing easy installation by others.

You are in a virtual environment for your Python project when you see the env name (in this case, literally env) to the left of the bash prompt.

Create

cd to project folder and then type:

python3 -m venv env

Activate

cd to project folder and then type:

source env/bin/activate

Deactivate

deactivate

Last modified: 202107020544

Datetime (Python)

These are some resources on how to use the datetime Python package.

Using datetime

datetime.datetime.now().isoformat() - to get a string of the current date and time

References

Last modified: 202107020541

Debounce (Python)

How to create and use a debouncer in Python.

In both of these examples, the inner function won't run until at least DEBOUNCE_TIME seconds has passed.

Standalone

from threading import Timer
import time

DEBOUNCE_TIME = 1  # 1 second
debounced_action = None


def debounce_action(message: str) -> None:
    """ Print the last message to be invoked within a certain amount of time """
    global debounced_action

    def print_message():
        print(message)

    if debounced_action:
        debounced_action.cancel()
    debounced_action = Timer(DEBOUNCE_TIME, print_message)
    debounced_action.start()


if __name__ == "__main__":
    debounce_action("Won't print this one")
    time.sleep(.5)
    debounce_action("Or this one")
    time.sleep(.99)
    debounce_action("This one will though!")

The benefit of using this standalone is that you can have multiple items debouncing with the same inner function and different parameters by using a dict to store the different debounced_actions instead of using a singular global.

Decorator

from threading import Timer
import time

DEBOUNCE_TIME = 1


def debounce(wait):
    """ Decorator that will postpone a functions
        execution until after wait seconds
        have elapsed since the last time it was invoked. """
    def decorator(fn):
        def debounced(*args, **kwargs):
            def call_it():
                fn(*args, **kwargs)
            try:
                debounced.t.cancel()
            except(AttributeError):
                pass
            debounced.t = Timer(wait, call_it)
            debounced.t.start()
        return debounced
    return decorator


@debounce(DEBOUNCE_TIME)
def print_message(message: str):
    print(message)


if __name__ == "__main__":
    print_message("Won't print this one")
    time.sleep(.5)
    print_message("Or this one")
    time.sleep(.99)
    print_message("This one will though!")

The benefit of using a decorator is you can throw it on any function that needs debouncing at it saves you the reuse of the debouncing code in multiple places.

References:

  1. https://gist.github.com/walkermatt/2871026

Last modified: 202107212152

SQLite

Data Types (version 3)

  • NULL
  • INTEGER
  • REAL (floating)
  • TEXT
  • BLOB (blob of data, stored exactly as it was input)

Primary Key

A column with type INTEGER PRIMARY KEY is an alias for the ROWID, which is always a 64-bit signed integer.

CREATE TABLE IF NOT EXISTS dogs (
  id INTEGER PRIMARY KEY,
  dog_name VARCHAR(10),
  good_boy INTEGER DEFAULT 1  -- Boolean, default is TRUE
);

PRAGMA

PRAGMA commands are SQLite specific and are meta commands regarding operation or non-table data.

Get column information of a given table

PRAGMA table_info(table_name)

References

  1. https://sqlite.org/pragma.html#pragma_table_info

Backlinks:

Last modified: 202105310513

SQL

SQL is a Structured Query Language that uses a relational database. A relational database represents a collection of related 2D tables, like spreadsheet. Tables of information about a certain thing hold rows that are specific instances of that thing with columns that show shared characteristics of those instances.

Database schemas describe the structure of each table and the datatypes that each column can contain.

Basic Syntax Rules

The end of a query is denoted with a semicolon.

Comments are made with --.

Whitespace and line returns are optional but often added for readability.

SQL queries are case insensitive, but by convention, the SQL commands and keywords are place in all capital letters to be easier to read by humans.

Creating/Using Databases

First, you want to see what databases exist using the SHOW DATABASES keyword.

SHOW DATABASES;

We will use the CREATE DATABASE keyword to initialize a database. TO enter into the database

CREATE DATABASE name;
USE name;

Creating/Altering Tables

SHOW TABLES;

CREATE TABLE / IF NOT EXISTS

What it sounds like, will make a new table. Use IF NOT EXISTS to skip if table exists. The structure of the table is defined by its table schema, which is a series of columns in the following parentheses.

CREATE TABLE friends (
  column DataType TableConstraint DEFAULT dafault_value,
  ...
);
CREATE TABLE IF NOT EXISTS dogs (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  dog_name VARCHAR(10),
  good_boy INTEGER DEFAULT 1  -- Boolean, default is TRUE
);

ALTER TABLE

Choose the table you want to modify with ALTER TABLE followed by the table name. Columns can be added by using the ADD COLUMN statement, removed by using the DROP statement, and renamed with RENAME TO.

ALTER TABLE dogs
RENAME TO dog_types
ADD COLUMN breed VARCHAR(20) AFTER col_name  -- can also use FIRST
DROP dog_name;

DROP TABLE / IF EXISTS

(Necessary XKCD): "Little Bobby Tables"

DROP TABLE will remove an entire table and all of the data from the database. IF EXISTS will make sure no error is thrown if the table doesn't exist.

DROP TABLE IF EXISTS problems;

Table Data Types

Data type Description
INTEGER, BOOLEAN The integer datatypes can store whole integer values like the count of a number or an age. In some implementations, the boolean value is just represented as an integer value of just 0 or 1.
FLOAT, DOUBLE, REAL The floating point datatypes can store more precise numerical data like measurements or fractional values. Different types can be used depending on the floating point precision required for that value.
CHARACTER(num_chars), VARCHAR(num_chars), TEXT The text based datatypes can store strings and text in all sorts of locales. The distinction between the various types generally amount to underlaying efficiency of the database when working with these columns. Both the CHARACTER and VARCHAR (variable character) types are specified with the max number of characters that they can store (longer values may be truncated), so can be more efficient to store and query with big tables.
DATE, DATETIME SQL can also store date and time stamps to keep track of time series and event data. They can be tricky to work with especially when manipulating data across timezones.
BLOB Finally, SQL can store binary data in blobs right in the database. These values are often opaque to the database, so you usually have to store them with the right metadata to requery them.

Table Constraints

Constraints are a special expression in the table's initialization that directs the table to operate in a specific way.

CREATE TABLE IF NOT EXISTS products (
  product_id INT AUTOINCREMENT,
  name TEXT,
  PRIMARY KEY(product_id)
);

CREATE TABLE IF NOT EXISTS reviews (
  review_id INT AUTOINCREMENT,
  product_id INT,
  FOREIGN KEY(product_id)
    REFERENCES products(product_id)
);
Constraint Description
PRIMARY KEY This means that the values in this column are unique, and each value can be used to identify a single row in this table.
AUTOINCREMENT For integer values, this means that the value is automatically filled in and incremented with each row insertion. Not supported in all databases.
UNIQUE This means that the values in this column have to be unique, so you can't insert another row with the same value in this column as another row in the table. Differs from the PRIMARY KEY in that it doesn't have to be a key for a row in the table.
NOT NULL This means that the inserted value can not be NULL.
CHECK (expression) This allows you to run a more complex expression to test whether the values inserted are valid. For example, you can check that values are positive, or greater than a specific size, or start with a certain prefix, etc.
FOREIGN KEY This is a consistency check which ensures that each value in this column corresponds to another value in a column in another table. For example, if there are two tables, one listing all Employees by ID, and another listing their payroll information, the FOREIGN KEY can ensure that every row in the payroll table corresponds to a valid employee in the master Employee list.

Queries/Retrieving Data

SELECT...FROM statements are queries of column FROM table. DISTINCT will remove results that are the same, meaning that they have matching sets of columns in the return. Certain columns could have duplicate values, but ALL of the columns need to match up to another result for it to be considered a duplicate.

SELECT columnName, anotherColumn 
FROM tableName;

SELECT DISTINCT columnName, anotherColumn 
FROM tableName;

WHERE

The WHERE clause helps filter out results via a condition. AND or OR can be used to chain these.

SELECT columnName, anotherColumn 
FROM tableName
WHERE a = b
  AND a = c
  OR c = b

Results of a query can be sorted via the ORDER BY keywords, followed by ASC or DESC (ASC is the default).

SELECT columnName, anotherColumn 
FROM tableName
WHERE a = b
ORDER BY columnName ASC;

Results can also be tested against whether a column's value is within a list of values.

SELECT columnName, anotherColumn 
FROM tableName
WHERE a IN ('list', 'of', 'values');

LIMIT/OFFSET

Results can be limited via the LIMIT and the OFFSET keywords. "The LIMIT will reduce the number of rows to return, and the optional OFFSET will specify where to begin counting the number rows from."

...
LIMIT num_limit OFFSET num_offset

CONCAT

CONCAT allows you to group the values of multiple fields together and call it a new 'field' upon return. CONCAT can take multiple arguments and strings to affix together.

SELECT * 
FROM clients c
WHERE c.client = 17
  AND c.client IN (
    # The following line combines the values of `active_client` and `alt_clients`, separated by a comma 
    # and effectively creates a new field called 'all_clients'.
    SELECT CONCAT(active_client, ',', alt_clients) AS all_clients 
    FROM users
    WHERE userId = 7070
  );

JOIN

We can join the data within two or more tables with the JOIN clause. The two tables can be linked by a certain column with ON followed by an expression. (note: OUTER is added in as a legacy keyword for SQL-92)

  • INNER: Using something that is constant among both tables, usually a key like ascending numbers like IDs or a common string, this will create rows containing both table's data. This will exclude any data that is not found in both tables at that common key.
  • FULL (OUTER): This will keep all rows from both tables within the query, even if a matching row does not exist within one of the tables.
  • LEFT (OUTER): This keeps anything from the table found after FROM (Left), even if no matching row is found in the table found after JOIN (Right).
  • RIGHT (OUTER): This keeps anything from the table found after JOIN (Right), even if no matching row is found in the table found after FROM (Left).

Inclusive/Exclusive

Inclusive JOINs will use the ON table1.key = table2.key, matching one column to another. Exclusive JOINs follow this with a filter on the focused table set to WHERE table.key IS NULL.

Where n is the two table's intersection, u is the union of the two tables, and - is exclusion.

  • INNER: AnB
  • LEFT (Including RIGHT): Au(AnB)
  • LEFT (Excluding RIGHT): A-B
  • RIGHT: (AnB)uB
  • RIGHT (Excluding LEFT): B-A
  • FULL/OUTER: AuBu(AnB)
  • OUTER (Excluding INNER): (A-B)u(B-A)
-- This is a venn diagram with both circles fully selected
SELECT * 
FROM table1
FULL JOIN table2 -- or INNER or LEFT, etc.
  ON table1.id = table2.id
-- This can be altered to exclude what overlaps
WHERE table1.id IS NULL 
  OR table2.id IS NULL

AS

Expressions, columns, and tables can all be given aliases using the AS keyword.

SELECT col_name AS foo -- 'col_name' has been aliased to 'foo'
FROM table_name AS bar; -- 'table_name' has been aliased to 'bar'

Aggregate Functions

Aggregate functions run on the entire column. They include operations like COUNT, MIN, MAX, AVG, and SUM, with the desired columns surrounded by parentheses.

-- returns a single entry with number of entries in col_name
SELECT COUNT(col_name) 
FROM table_name;

-- returns a single entry with lowest ERA of all pitcher data
SELECT MIN(era) 
FROM pitcher_stats;

These functions can also be run on subsections of these columns using GROUP BY, followed by which segments should be calculated together.

-- returns an entry for the player with lowest ERA on each team
SELECT player_name, 
  MIN(era) FROM pitcher_stats
GROUP BY team_name;

Further filtering of what should be included in each GROUP can be done with HAVING, which operates like WHERE on the GROUP BY element.

-- returns an entry for the player with lowest ERA above 2 on each team
SELECT player_name, 
  MIN(era) FROM pitcher_stats
GROUP BY team_name
HAVING era > 2;

EXISTS - Boolean Check

You can use SELECT EXISTS (...) with an enclosed query to return either a 0 (false) or 1 (true) on if any rows were returned.

-- will return 1 if any rows are found where the name field contains 'John'
SELECT EXISTS (
  SELECT * 
  FROM example_table
  WHERE name = 'John'
);

Order of Query Execution

  1. FROM and JOIN (loading in data)
  2. WHERE (filtering data)
  3. GROUP BY (creating groups)
  4. HAVING (filtering data for each group)
  5. SELECT (selecting the columns)
  6. DISTINCT (removing duplicates)
  7. ORDER BY (organizing results)
  8. LIMIT and OFFSET (limiting results)

Adding/Changing Rows

INSERT INTO / VALUES

The INSERT INTO statement describes which table will have data inserted, and the VALUES statement includes all the values of the given row that will go into each column enclosed by parentheses and separated by commas within it. VALUES can correspond to multiple rows by separating the sets of values by commas.

With incomplete data or default values, you can choose which exact columns you want to add data to by following INSERT INTO table_name with a set of columns within parentheses and separated by commas. Inserting data this way ensures forward compatibility, as any new columns that are hardcoded into later versions of the table will not be affected.

INSERT INTO mytable (column_name, another_column_name)
VALUES (value_or_expr, another_value_or_expr),
  (value_or_expr_2, another_value_or_expr_2);

UPDATE / SET

UPDATE is followed by the name of the table, with SET followed by column_name = value_or_expr pairs. These can be used in conjunction with WHERE to filter which rows you want updated.

It is recommended to query the items you are going to update before updating them, to ensure you are correctly select what you want.

-- Update all costs of candy in food I like by raising them 3%
UPDATE food_i_like
SET cost = cost * 1.03,
  updated = "2021-01-01"
WHERE 
  type = "candy";

DELETE FROM

The DELETE statement describes the table to focus on, with WHERE describing which rows to delete (leaving out WHERE will delete the entire table!). If you only are trying to get rid of one thing, use LIMIT 1 to redundantly ensure you do.

It is recommended to query the items you are going to delete before updating them, to ensure you are correctly selecting what you want.

DELETE FROM food_i_like
WHERE name = "Good & Plenty"  -- always have WHERE to limit deletion
LIMIT 1;  -- always include this to limit deletion to ONLY one row

Variables

A SQL variable is defined by calling DECLARE followed by the variable name preceded by the @ symbol, after which you declare the type. To set the value, use the SET keyword followed by the assignment. In MySQL, you only use the SET keyword followed by either an equals or a colon-equals.

DECLARE @NewVariable AS VARCHAR(50);
SET @NewVariable = "Cool!";

Meta Operators

Name Function
(boolean expression) AND (boolean expression) WIll return true if both are true
(boolean expression) OR (boolean expression) Will return if either is true

Conditional Operators

Operator Condition SQL Example
=, !=, < <=, >, >= Standard numerical operators col_name != 4
BETWEEN … AND … Number is within range of two values (inclusive) col_name BETWEEN 1.5 AND 10.5
NOT BETWEEN … AND … Number is not within range of two values (inclusive) col_name NOT BETWEEN 1 AND 10
IN (…) Number exists in a list col_name IN (2, 4, 6)
NOT IN (…) Number does not exist in a list col_name NOT IN (1, 3, 5)
IS NULL/IS NOT NULL Value is or is not NULL col_name IS/IS NOT NULL

Expressions

Many different types of expressions can be used with: WHERE to better filter results; and SELECT to create new columns of results (column expressions). While there are a few different types of expressions, the examples below are both numeric type expressions. Expressions can also utilize aggregate functions.

-- Used in WHERE; filters above 0° Celsius
SELECT Temperature FROM 2000_Temp_Data
WHERE ((Temperature - 32) * 5) / 9 > 0;

-- Used in a column expression, displays another column named 'Celsius'
SELECT Fahrenheit, ((Temperature - 32) * 5) / 9 AS Celsius
FROM 2000_Temp_Data;

References

  1. Common SQL Queries
  2. https://sqlbolt.com/
  3. https://www.mysqltutorial.org/mysql-primary-key/
  4. https://www.educba.com/mysql-constraints/

Backlinks:

Last modified: 202107140250

SQLite3 (Python)

How to use SQLite with Python.

Opening/Closing Connections and Command Execution

After importing the built-in sqlite3 module, you need to establish a connection with your database.

import sqlite3

conn = sqlite3.connect("database.db") # if found at filepath
conn = sqlite3.connect(":memory:")    # to use RAM (flushed after use)

After creating the connection, create a cursor object and use it to run SQL commands via execute.

c = conn.cursor()
c.execute("""--sql-goes-here""")

Once all commands have been run, be sure to commit your changes and close the connection.

conn.commit()
conn.close()

.fetchone() and .fetchall()

After you have executed a SELECT command, you can use the cursor as an iterator with fetchone(), which will recall each returned row one by one, or fetchall() to return all rows at once.

Get table names from database

SELECT name 
FROM sqlite_master 
WHERE type = 'table';

References

  1. https://docs.python.org/3/library/sqlite3.html
  2. https://sqlite.org/autoinc.html
  3. https://sqlite.org/datatype3.html

Last modified: 202107020543

Numpy

This is the standard way to import Numpy into your Python project, and it's good practice.

import numpy as np

Arrays

If modifying the array, ensure you make a copy of the array through copy.deepcopy

import numpy as np
import copy
arr = np.array([1,2,3])
a = copy.deepcopy(arr)

Make a multidimensional array

# 3D
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
result = np.array(arr)
# 2D
arr = [ [1,2,3,4], [5,6,7,8], [9,10,11,12] ]
result = np.array(arr)
# 3D
arr = [ [ [1,2], [3,4] ], [ [5,6], [7,8] ], [ [9,10], [11,12] ] ]
result = np.array(arr)

Make a multidimensional array filled with something

# returns a 3x5 2D array filled with '.'s
arr = np.full((3, 5), '.')

Get length of each side

np.size(array_name, axis_number)
print('Axis 0 size : ', np.size(arr3D, 0))
print('Axis 1 size : ', np.size(arr3D, 1))
print('Axis 2 size : ', np.size(arr3D, 2))

Accessing elements

1D Arrays can be accessed via indexing just like an array. 2D and higher use a slightly different syntax.

Axes are represented as (Y, X) in 2 dimensional arrays, as in (row, column).

# 2D
arr = [ [1,2,3,4], [5,6,7,8], [9,10,11,12] ]
element = arr[0,0] # 1
element = arr[1,2] # 7

Iteration

To iterate through every element within the array, going through all dimensions:

import numpy as np
arr = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
for x in np.nditer(arr):
    print(x)

If you want indexes enumerated over also, as a tuple:

for index, x in np.ndenumerate(arr):
    print(index, x)

References:

  1. https://numpy.org/doc/stable/reference/generated/numpy.full.html
  2. https://stackoverflow.com/questions/5891410/numpy-array-initialization-fill-with-identical-values
  3. https://thispointer.com/how-to-get-numpy-array-dimensions-using-numpy-ndarray-shape-numpy-ndarray-size-in-python/
  4. https://www.w3schools.com/python/numpy_array_indexing.asp
  5. https://www.sharpsightlabs.com/blog/numpy-axes-explained/
  6. https://stackoverflow.com/questions/17079279/how-is-axis-indexed-in-numpys-array
  7. https://stackoverflow.com/questions/37593013/deep-copy-of-a-np-array-of-np-array

Last modified: 202107020542

Math (Python)

Get Quotient and Remainder

divmod returns a tuple of the quotient and the remainder/modulo.

divmod(20, 3) # (6, 2)

Round Decimals

The round function in Python allows you to round your decimal. The arguments taken are:

# round(number, decimal_places)
round(3.1415926, 3)  # 3.142

References

  1. https://tutorialdeep.com/knowhow/round-float-to-2-decimal-places-python/

Last modified: 202107020542

JSON (Python)

Load JSON from file

def load_json(fp):
    with open(fp, 'r') as f:
        output = json.load(f)
    return output

Save to JSON file

def save_json(fp):
    with open(fp, 'w') as f:
        # with pretty output kwargs
        json.dump(sample, f, indent=4, sort_keys=True)

References:

  1. https://docs.python.org/3/library/json.html
  2. Python

Last modified: 202107020542

Cube CSS

Cube CSS is a CSS framework that is composition first and values it above everything else. The thesis is that when things work together and have a harmony between their design and structure, the amount of work that will need to be done later will be minimal.

Base CSS

These are all of your resets ((removing margins, list styles, setting default image width, etc.) and basic choices that will apply to all of your HTML.

Composition

This is where the bulk of your stylistic choices will be made and they will be made as classes that will be applied.

Utilities

Block

Exception

References

  1. https://every-layout.dev/layouts/stack/
  2. https://alistapart.com/article/axiomatic-css-and-lobotomized-owls/
  3. https://every-layout.dev/rudiments/modular-scale/
  4. https://issue33.com/
  5. https://github.com/hankchizljaw/modern-css-reset

Last modified: 202107020522

Selectors (CSS)

Selectors are the backbone of CSS, allowing the developer to create stylesheets that apply and cascade to many elements at a time.

Selectors

  • type
  • #id
  • .class
  • [attribute] - Select all elements with attribute
    • [attribute="X"] - Select elements with attribute of value 'X' (e.g. attribute="X")
    • [attribute~="X"] - Select elements with an attribute that contains value 'X' (e.g. attribute="W X Y Z")
    • [attribute*="X"] - Select elements with an attribute that contains substring 'X' (e.g. attribute="WXYZ")
    • [attribute^="X"] - Select elements with attribute that starts with 'X' (e.g. attribute="XYZ ABC" but not "ABC XYZ")
    • [attribute|="X"] - Select elements with attribute that has value 'X' or begins with 'X-' (e.g. attribute="X-YZ")
    • [attribute$="X"] - Select elements with attribute that ends with 'X' (e.g. attribute="VWX")
    • [... i] - Make selection of the quoted value case insensitive
  • A B - Select all elements B that are inside of A
  • A + B - Select all elements B that are adjacent to and come directly after A
  • A ~ B - Select all elements B that are adjacent to and come after A at some pont
  • A > B - Select all elements B that are direct children of A

Pseudoclasses

Pseudoclasses are prefaced by a single colon.

Parent

  • A:empty - Select element A if they have no child elements

Child

  • A:first-child
  • A:last-child
  • A:nth-child(n)
  • A:nth-last-child(n) - Select every nth element of A counting from the last element to the first
  • A:only-child - Select element A if they are the only child element of their parent element
  • B A:only-child - Select element A if they are the only child element of parent element B

Type

  • A:first-of-type - Select the first element of type A
  • A:nth-of-type(n/even/odd) - Select the nth element of type A or every even or odd numbered instance of element of type A
  • A:nth-of-type(Nn+X) - Select every Nth element of A starting on and including offset X (e.g. A:nth-of-type(2n+3) will select every odd element starting on element 3)
  • A:only-of-type - Select A if it is the only child of that type
  • A:last-of-type - Select the last of element type A

State

Links

  • A:link - Select A if it is an anchor element
  • A:visited
  • A:hover
  • A:active - Select A if it has been selected

a:hover MUST come after a:link and a:visited in the CSS definition in order to be effective. a:active MUST come after a:hover in the CSS definition in order to be effective. "LoVe, HAte"

If you want to select an element when hovering over an element:

.parent-selector:hover .child-selector { ... } /* Child */
.parent-selector:hover + .sibling-selector { ... } /* Sibling */
/* etc. */

Forms and Inputs

  • A:focus - Select A if it currently has focus (e.g. text input when selected)
  • A:invalid - Select A if it currently has an invalid entry (e.g. not matching the pattern)
  • A:focus:invalid - Select A if it has focus and has an invalid entry
  • A:placeholder-shown - Select A if the placeholder is being shown

Anchor/URL Hash

  • A:target - Select A if the #id of A is the suffix of the URL.
/* <div id="cool-thing" class="thing"></div> */
/* if URL is index.html#cool-thing, put border around the div with id "cool-thing" */

.thing:target {
  border: 10px solid red;
}

Meta

  • A:not('X') - Select all A elements if they do not match selector or pseudoclass X (e.g. #id, .class, :last-child, etc.)

Pseudoelements

Pseudoelements are prefaced by two colons.

  • A::placeholder - Select the placeholder within element A (e.g. placeholder text of a text input box)
  • A::first-line - Select the first line of a block element.
  • A::first-letter - Select the first letter of an element.

Content

The ::before and ::after pseudoclasses allow you to place content before or after the selection. They require a content property and a display property. These pseudoclasses are treated like children of the selected element. e.g. 100% width is 100% width of the selected element.

.selector::after {
  content: "";
  display: inline-block;
  height: 100%;          /* same width/height as parent */
  width: 100%;
  border-radius: 100px;
  position: absolute;
  top: 0;                /* same position as parent */
  left: 0;
  z-index: -1;
}

References

  1. https://www.w3schools.com/cssref/css_selectors.asp
  2. https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors

Backlinks:

Last modified: 202107020516

Transitions (CSS)

Transitions allow you to transform a CSS rule from one set of values to another, and can be triggered either by a pseudoclass selector, on a regular cycle, or just once when loaded.

This example I modified from MDN shows how you would transform the background color of a button on hover:

#button {
  background-color: rgba(0, 2, 143, 1);
  transition-property: background-color;
  transition-duration: 4s;
  transition-timing-function: ease;
  transition-delay: 2s;
}

#button:hover {
  background-color: rgba(0, 2, 143, 0.5);
}

References:

  1. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions

Last modified: 202107020518

Minimalist CSS

This CSS code makes really beautiful text-centric websites that are responsive and look nice with only like 54 bytes or something? I use this as a basis all the time for making nice looking pages.

main {
  max-width: 38rem;
  padding: 2rem;
  margin: auto;
}

References

  1. https://jrl.ninja/etc/1/

Last modified: 202107020511

Fonts (CSS)

Importing and using external fonts properly in CSS.

Using @font-face

@font-face {
  font-family: 'Verlag Condensed Bold';
  src: url('https://brandlive-upload.s3-us-west-2.amazonaws.com/933/documents/1wp6lcexy4/verlagcondensedbold.otf');
  [ unicode-range: <unicode-range>; ] ||
  [ font-variant: <font-variant>; ] ||
  [ font-feature-settings: <font-feature-settings>; ] ||
  [ font-variation-settings: <font-variation-settings>; ] ||
  [ font-stretch: <font-stretch>; ] ||
  font-weight: bold;
  [ font-style: <font-style>; ]
}

You can include multiple src values via a call to the user's fonts via local("Font Name"), url("..."), as well as specifying formats after the url (url("...") format("truetype"),), all separated by commas and ending with a semicolon.

@import vs. <link>

To bring in another stylesheet with a font attached, Google Fonts and others offer an @import option. This unfortunately is blocking and and will delay all other loading until that import is complete. Instead, include the url in a <link> and it will load all elements at the same time.

<link href='http://fonts.googleapis.com/css?family=Judson:400,400italic,700' rel='stylesheet' type='text/css'>

References

  1. https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face

Last modified: 202107020507

Sass

Sass is a CSS preprocessor that allows a lot more ease in maintainability and gives much deeper modularity than CSS normally provides. Sass is a language that compiles into CSS, most often used in it's .scss variant, as it is much more similar to normal CSS than its counterpart (.sass).

Setup/Meta

Install Sass

On Mac, use brew install sass/sass/sass to install the newest version of Sass on your machine.

Command Line Options

  • path/to/input.scss:path/to/output.css - Compile the input file to output file
  • path/to/inputfiles/:path/to/outputfiles/ - Compile any SCSS files within input directory to output directory as CSS
  • --watch path/to/input.scss:path/to/output.css - Continuously watch the input file and compile it on change to output file
  • --watch path/to/inputfiles/:path/to/outputfiles/ - Continuously watch the input directory and compile any SCSS files within to output directory as CSS on change
  • -v - Output the current version that is being run
  • --sourcemap=none / --no-source-map - Don't output a source map on compile (former for Ruby Sass, latter for Dart Sass

Syntax

Comments

Comments are done using the standard Javascript syntax: // and /* */ for multiline.

Variables

Variables, like --variable in CSS3, are done by prepending the variable name with a dollar sign

$variable-name: value;

When variables are used in a calc function, the variable needs to be surrounded by #{ }.

width: calc(100% - #{$variable});

Nesting

Instead of writing many specific selectors, you can use nesting to enclose selectors that are children of other selectors. Using an ampersand before a nested selector will write out the selector that is in use at that point in its place when compiled.

Nesting is extremely useful in BEM, as the otherwise long and ugly class names become much more easy to read and navigate. In Sass, the & is shorthand for the entire selector at that point.

// bad
.block { ... }
.block--modifier { ... }
.block__element { ... }
.block__element:hover { ... }
.block__element--modifier { ... }

// good
.block {
  ...

  &--modifier {  // & === `.block`
    ...
  }

  &__element {
    ...

    &:hover {
      ...
    }

    &--modifier {
      ...
    }
  }
}

Mixins

Mixins are a group of declarations or rules that can be reused throughout by copying their contents into a rule. They can also include parameters for dynamic value generation. The mixin is defined by using @mixin and then called with @includes and the name.

// with mixin using parameters
@mixin box-shadow($x, $y, $blur, $c){
 -webkit-box-shadow: $x $y $blur $c;
    -moz-box-shadow: $x $y $blur $c;
     -ms-box-shadow: $x $y $blur $c;
         box-shadow: $x $y $blur $c;
}

div {
 @include box-shadow(0px, 0px, 4px, #fff);
}

// compiled result
div {
 -webkit-box-shadow: 0px 0px 4px #fff;
    -moz-box-shadow: 0px 0px 4px #fff;
     -ms-box-shadow: 0px 0px 4px #fff;
         box-shadow: 0px 0px 4px #fff;
}

Functions

Functions are created by using @function with a name and a parameter list. Inside the function, a @return is required. It is common when a raw number is returned to multiply it by 1 * unit, with unit being px, em, etc.

@function divide($a, $b) {
  @return $a / $b;
}

// called
p {
  margin: divide(60, 2) * 1px;
}

Conditionals

@if, @else if, and @else are what they sound like and are used within a mixin.

@mixin make-bold($bool) {
  @if $bool == true {
    font-weight: bold;
  }
}

@mixin text-effect($val) {
  @if $val == danger {
    color: red;
  }
  @else if $val == alert {
    color: yellow;
  }
  @else if $val == success {
    color: green;
  }
  @else {
    color: black;
  }
}

Iteration

For loops including the last number, use through. For loops excluding the last number, use to.

@for $i from 1 through 12 {
  .col-#{$i} { width: 100%/12 * $i; }
}

@for $i from 1 to 13 {
  .col-#{$i} { width: 100%/12 * $i; }
}

For each loops are done with @each.

@each $color in blue, red, green {
  .#{$color}-text {color: $color;}
}

//alternative
$colors: (color1: blue, color2: red, color3: green);
@each $key, $color in $colors {
  .#{$color}-text {color: $color;}
}

While loops are done with @while.

$x: 1;  /* define variable `x` as 1 */
@while $x < 13 {
  .col-#{$x} { width: 100%/12 * $x;}
  $x: $x + 1;
}

Imports/Partials

You can create separate stylesheets and import them in to your main sheet.

Partials are what will be imported into the main sheet. These filenames start with an underscore and end with .scss.

Depending on the version of Sass that is being used, they use @import or @use followed by the partial enclosed in single quotes without the underscore or the extension. (@import is being phased out, so if you can, use @use)

// partial file is at fp "./base/_base.scss"

// if using Dart Sass:
@use 'base/base';
// else
@import 'base/base';

https://www.freecodecamp.org/learn/front-end-libraries/sass/split-your-styles-into-smaller-chunks-with-partials

Extending Rules

Rules can be extended from one element to another one through copying the rules and then further modification (header -> small-header). @extend followed by the original selector. Extend can also be used on a placeholder rule, defined by using a preceding %.

Extensions should be used only when the elements it is extending are inherently and thematically related, but extend is generally not advised because you will be "distributing selectors across [your] codebase for purely circumstantial reasons", leading to bloated and difficult to maintain code.

The difference between this and a mixin is instead of bringing code into another rule, we are bringing the selectors that include the extend command to the rule.

%panel {
  background-color: red;
  height: 70px;
  border: 2px solid green;
}

.big-panel {
  @extend %panel;
  width: 150px;
  font-size: 2em;
}

.long-panel {
  @extend %panel;
  width: 1000px;
}

// compiled result
.big-panel,
.long-panel {
  background-color: red;
  height: 70px;
  border: 2px solid green;
}

.big-panel {
  width: 150px;
  font-size: 2em;
}

.long-panel {
  width: 1000px;
}

References

  1. https://www.udemy.com/course/advanced-css-and-sass
  2. https://www.freecodecamp.org/learn/front-end-libraries/sass/
  3. https://sass-lang.com/documentation/at-rules/import
  4. https://sass-lang.com/documentation/at-rules/use
  5. https://sass-lang.com/guide

Backlinks:

Last modified: 202107020549

Inverted Triangle CSS

ITCSS is a way to structure your CSS projects to minimize specificty issues and organizational problems. ITCSS is not a naming convention.

ITCSS is most effective when used with a preprocessor like Sass, Less, etc.

Principles

The inverted triangle refers to how your CSS project should be put together. At the beginning, we have the most far-reaching, least specific, and most generic styles possible. This includes variables, sitewide styles like font-settings, and CSS resets. As we go farther in the file, we get more localized, more specific, and more explicit styles. This includes component-specific styles and rules.

Layers

The inverted triangle has layers from top to bottom, representing the amount of reach each layer should have; the first layers have the most, decreasing their reach the farther down you go.

The first two layers should not generate any CSS on their own if being used with a preprocessor.

  1. Settings - Variables
  2. Tools - Any mixins or functions that need to be globally available. If they don''t need to be globally available, they should go somewhere else.
  3. Generic - Includes Normalize, resets, box-sizing rules, etc.
  4. Elements - These are the styles that refer to unclassed HTML elements. Changing the font-size of headings, the focus styles on inputs, or default anchor and link behavior.
  5. Objects - Undecorated design patterns, like wrappers, containers, rows, grids, etc.
  6. Components - Specific UI components. Most of our styling should go here, as most UI components should be composed of objects and components.
  7. Utilities (Trumps) - Anything that should be able to override the previous styles.

BEMIT

This framework can be combined with BEM to make the HTML more readable for the developer. Using the standard Block, Element (__), Modifier (--) syntax, we can also use prefixes and suffixes to make their functionality more clear.

Prefixes

  • o- - Object
  • c- - Component
  • u- - Utility/Trump
  • is-/has- - State
  • js- - Javascript hook
  • _ - Outright hacks

Suffixes

  • @ - Responsive media or print queries (need to escape @ in CSS with \@)

References

  1. https://www.freecodecamp.org/news/managing-large-s-css-projects-using-the-inverted-triangle-architecture-3c03e4b1e6df/
  2. https://csswizardry.com/2015/08/bemit-taking-the-bem-naming-convention-a-step-further/
  3. http://www.jamesturneronline.net/blog/bemit-naming-convention.html

Last modified: 202107020524

Object Oriented CSS

Another CSS framework

Main Principles

  1. Separate structure and skin - Structure and position declarations should be in the base object (along with default visual declarations if necessary), while any visual declarations should go into extender classes.
  2. Separate container and content - Break the dependency between the container module and the content objects in contains

More Best Practices

  1. Create a component library - Make components (legos) with which you can build your site. These components could include headers, lists, media components, etc. Build these before building your site.
  2. Extend objects by applying multiple classes to an element - Don't make one class do everything. Utilities, modifiers, and base classes can combine to make a much easier to maintain style.
  3. Minimize selectors - Low specificity means less cascade problems and runaway specificity races.
  4. Use consistent semantic styles
  5. Design modules to be transparent on the inside
  6. Be flexible - Height and width should be able to adapt themselves and should not rely on constant babysitting by the designer/developer.
  7. Learn to love grids

9 Pitfalls

  1. Avoid location dependent styles - You want your code to be modular. If it only works if it is in a certain context or position, it is not modular and prone to breakage.
  2. Avoid specifying what tag a class applies - A 'heading' should do something predictable from page to page.
  3. Avoid IDs - They add unnecessary specificity errors and can only be used once, so are needlessly specific.
  4. Avoid drop shadows and rounded corners over irregular backgrounds - This may cause undesired results
  5. Avoid height alignment - Height should be defined by the content of the element. Instead of this, ensure you are separating the container from the content.
  6. Don't use images as text - Screen readers and users on older software often rely on text only and this will make pages needlessly difficult to use.
  7. Avoid redundancy - If two components look too similar to be used on the same page, they are too similar to use on the same site. Choose one!
  8. Avoid premature optimization - If you are unsure what is the best choice, do the naive solution first, and then refactor afterwards.
  9. Don't sprite every image together, unless you have very few pages (seems like dated advice at this point)

Grids control width, content controls height

References

  1. https://www.slideshare.net/stubbornella/object-oriented-css/37-Avoid_redundancy
  2. https://www.benmarshall.me/oocss-object-oriented-css/
  3. https://www.slideshare.net/stubbornella/our-best-practices-are-killing-us

Last modified: 202107020525

Vendor Prefixes (CSS)

Vendor prefixes are used to ensure that older or unsupported browsers have every possibility of implementing the desired rule. Vendor prefixes are before the declarations and denote which tech/browser/setup it is intended for.

div {
  -webkit-box-shadow: 0px 0px 4px #fff;
     -moz-box-shadow: 0px 0px 4px #fff;
      -ms-box-shadow: 0px 0px 4px #fff;
          box-shadow: 0px 0px 4px #fff;
}

Using Sass

Sass mixins allow browser prefixes to be done easily.

Using Autoprefixer

You can run Autoprefixer on your CSS to add the prefixes needed on your completed CSS.

Do I have to?

Find out if you do here:

References

  1. https://css-tricks.com/snippets/sass/mixin-prefix-properties/

Backlinks:

Last modified: 202107020520

Typography (CSS)

How to properly define and apply typography rules in CSS.

Line Height

The normal value on a line-height property in CSS is calculated as 1.2x the font size; e.g. a font size of 16px will have a normal line height of (1.2 * 16)px = 19.2px.

When setting a defined line-height, use the em unit to set it relative to the current font-size.

Best Practices

1.5em is the most common line height for copy.

  • The longer the line length, the taller the Line-height should be.
  • The shorter the line length, the shorter the Line-height should be.
  • Use a taller line-height with continuous copy.
  • Use taller line-heights with large x-height fonts.
  • The ascenders and descenders of the lines of text should not touch.
  • Place the lines close enough together that the reader requires no effort to find the next line, then balance the height based on the line length.

References

  1. http://smad.jmu.edu/shen/webtype/lineheight.html
  2. https://www.madebymike.com.au/writing/precise-control-responsive-typography/
  3. https://blog.typekit.com/2016/08/17/flexible-typography-with-css-locks/

Last modified: 202107020519

Alignment (CSS)

Block Elements

To horizontally center a block element with a width other than 100%, use margin: auto;. Setting the width of the element will prevent it from stretching out to the edges of its container. The element will then take up the specified width, and the remaining space will be split equally between the two margins.

Inline and Inline-Block Elements

Horizontal alignment can be done using text-align: center;.

To align text vertically, however, the vertical-align property is used. The vertical-align property works only with inline and table-cell elements — it won’t work for block, inline-block, or any other element levels. The vertical-align property accepts a handful of different values; the most popular values are top, middle, and bottom. These values vertically position text in relation to the table cell, for table-cell elements, or to the closest parent element, for inline-level elements.

Image/Icon/Font Awesome Alignment

Although the text needs to be aligned with the image, it is actually the image that needs to be aligned and the text will move accordingly.

<style>
  .icon {
    vertical-align: middle;
  }
</style>

<span>Some text <img class="icon" src="..."></span> <!-- or ... -->
<span>Some text <i class="icon fa ..."></i></span>

Using 100vh/100vw

100vh and 100vw won't work as expectedunless you set the margin and padding of the selected element to 0.

References

  1. https://css-tricks.com/centering-css-complete-guide/
  2. https://learn.shayhowe.com/html-css/organizing-data-with-tables/
  3. https://stackoverflow.com/questions/17309928/how-to-center-text-vertically-with-a-large-font-awesome-icon

Last modified: 202107020504

Position (CSS)

The position property in CSS gives the developer control over the x-, y-, and z-axis in aligning elements.

  • static - This is the default position that a property will have if left unset. The equivalent of being unpositioned. This element will be in the standard flow of the document. This value is the only value that will not create a new stacking context (z-axis).
  • relative - A relatively positioned element will be in the standard flow of the document, but can be positioned relative to its current position (e.g. top, left, bottom, right). This offset doesn't affect other elements in flow. Space will still exist in flow for this element in it's original position, even if it is moved. relative can create a new stacking context if the z-index is not set to auto.
  • absolute - An absolutely positioned element will be out of the regular flow of the document and can be positioned according to the closest positioned (not static) parent element. No space will be made for it in the document. This can create a new stacking context if the z-index is not set to auto.
  • fixed - Like absolute, a fixed element will be removed from the standard flow and no space will be made. This will be positioned according to the box created by the browser's viewport. This will always create a new stacking context and will print on every document when printed.
  • sticky - This is positioned in a normal flow of a document, like relative, and then offset to it's nearest scrolling relative (i.e. has an overflow property set to a scrolling value). This will also always create a new stacking context.

References

  1. https://developer.mozilla.org/en-US/docs/Web/CSS/position

Last modified: 202107020513

Color Palettes (CSS)

https://monokai.pro/

:root {
  --red:    #ff6188;
  --orange: #fc9867;
  --yellow: #ffd866;
  --green:  #a9dc76;
  --blue:   #78dce8;
  --purple: #ab9df2;

  --white:  #fdf9f3;
  --gray:   #bcbbbb;
  --black:  #2c292d;
}

https://github.com/mrmrs/colors

/* 
   VARIABLES
   - Cool
   - Warm
   - Gray Scale
*/

:root {
  --aqua:  #7FDBFF;
  --blue:  #0074D9;
  --navy:  #001F3F;
  --teal:  #39CCCC;
  --green: #2ECC40;
  --olive: #3D9970;
  --lime:  #01FF70;

  --yellow:  #FFDC00;
  --orange:  #FF851B;
  --red:     #FF4136;
  --fuchsia: #F012BE;
  --purple:  #B10DC9;
  --maroon:  #85144B;

  --white:  #FFFFFF;
  --silver: #DDDDDD;
  --gray:   #AAAAAA;
  --black:  #111111;
}

Windows 3.1

/* 
   VARIABLES:
   - Dark
   - Bright
   - Grayscale
*/

:root {
  --dark-red:    #7e0000; /* maroon */
  --dark-yellow: #7e7e00; /* olive */
  --dark-green:  #047e00; /* plant green */
  --dark-cyan: #047e7e; /* teal */
  --dark-blue:   #00007e; /* navy blue */
  --dark-purple: #7e007e; /* plum */

  --red:    #fe0000;
  --yellow: #ffff04;
  --green:  #06ff04; /* neon green */
  --cyan:   #06ffff; /* aqua */
  --blue:   #0000ff;
  --purple: #fe00ff; /* fuschia */

  --white:     #000000;
  --gray:      #7e7e7e;
  --dark-gray: #bebebe;
  --black:     #ffffff;
}

Original VGA

/* 
   VARIABLES:
   - Dark
   - Bright
   - Grayscale
*/

:root {
  --dark-red:    #aa0000; /* candy apple */
  --dark-orange: #aa5500; /* tan */
  --dark-green:  #00aa00; /* grass */
  --dark-cyan:    #00aaaa; /* tiffany blue */
  --dark-blue:   #0000aa; /* deep blue */
  --dark-purple: #aa00aa; /* magenta */

  --red:    #ff5555; /* coral */
  --yellow: #ffff55; /* daffodil */
  --green:  #55ff55; /* slime */
  --cyan:   #55ffff; /* cyan */
  --blue:   #5555ff; /* light blue */
  --purple: #ff55ff; /* pink */

  --white:      #ffffff;
  --gray-light: #aaaaaa;
  --gray-dark:   #555555;
  --black:      #000000;
}

Colorblindness Colors

https://jfly.uni-koeln.de/color/#pallet

From their page:

This is a proposal of color pallet that is 1: unambiguous both to colorblinds and non-colorblinds, 2: with vivid colors so that color names are easy to identify, 3: can be printable with similar color both on screen and when printed.

  • For red, vermilion is used since it is recognizable also to protanopes.

  • Colors between yellow and green are all avoided, since they are indistinguishable with yellow and orange.

  • For green, bluish green is chosen so that it won't be confused with red or brown.

  • Since violet is close to blue and appear the same to colorblinds, reddish purple is chosen.

  • Between vermilion and yellow, three colors with different apparent intensity is selected.

  • Sky blue and blue are chosen so that they are distinguishable with there difference in brightness and saturation.

  • Even for non-coloblinds, thin lines and small characters in blue and yellow are hard read. For thin lines and small objects, use darker blue and orange is preferable to sky blue and yellow.

When combining colors from this pallet,

  • Use "warm" and "cool" colors alternatively.
  • When using two warm colors or two cool colors, put distinct differences in brightness or saturation.
  • Avoid combination of colors with low saturation or low brightness.
/* 
   VARIABLES:
   - Dark
   - Bright
   - Grayscale
*/

:root {
  --black: rgba(0,0,0);
  --orange: rgba(230,159,0);
  --sky-blue: rgba(86,180,233);
  --bluish-green: rgba(0, 158, 115);
  --yellow: rgba(240,228,66);
  --blue: rgba(0,114,178);
  --vermillion: rgba(213,94,0);
  --reddish-purple: rgba(204,121,167);
}

Misc Colorsets

https://lospec.com/palette-list/1bit-monitor-glow

--black: #222323;
  --white: #f0f6f0;

TI Calculators

--black: #1E1F1A;
  --white: #b7b9ab;

Toshiba 3200

--black: #600D00;
  --dark-gray: #b81903;
  --gray: #da3f1b;
  --white: #fe591f;

Gameboy

--black:     #081820;
  --dark-gray: #346856;
  --gray:      #88c070;
  --white:     #e0f8d0;

Last modified: 202107020505

Text Selections (CSS)

How to use CSS to give or take away the user's ability to select text on a page.

Disable

Particularly with span or div style buttons that can be clicked a bunch and end up with their text selected.

.disable-select{
  -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
     -khtml-user-select: none; /* Konqueror HTML */
       -moz-user-select: none; /* Firefox */
        -ms-user-select: none; /* Internet Explorer/Edge */
            user-select: none; /* Non-prefixed version, currently
                                  supported by Chrome and Opera */
}

Select All

This allows all the inner text to be copied when clicking inside the selected element.

.copy-all-text{  
  -webkit-user-select: all;  /* Chrome all / Safari all */
     -moz-user-select: all;  /* Firefox all */
      -ms-user-select: all;  /* IE 10+ */
          user-select: all;  /* Likely future */   
}

References

  1. https://www.freakyjolly.com/how-to-disable-text-selection-highlighting/

Last modified: 202107020517

Organization and Structure (CSS)

Miscellaneous notes and best practices on organization and structure in CSS.

Best Practices

Keep it consistent

If you get to set the rules for the project or are working alone, then the most important thing to do is to keep things consistent. Consistency can be applied in all sorts of ways, such as using the same naming conventions for classes, choosing one method of describing color, or maintaining consistent formatting (for example will you use tabs or spaces to indent your code? If spaces, how many spaces?)

If you are working with a team on an existing project, the first thing to check is whether the project has an existing style guide for CSS. The team style guide should always win over your own personal preferences. There often isn't a right or wrong way to do things, but consistency is important.

Organize Code with Comments

Adding comments to your CSS will help any future developer work with your CSS file, but will also help you when you come back to the project after a break. A good tip is to add a block of comments between logical sections in your stylesheet too, to help locate different sections quickly when scanning through, or even give you something to search for to jump right into that part of the CSS. If you use a string which won't appear in the code you can jump from section to section by searching for it.

/* || General Styles */
...
/* || Utilities */

Build Proficient Selectors

Don't use IDs in your selectors. This messes with the specificity and often breaks cascades. In general, in seems like it's best practice to stick with classes as your selectors.

Keep selectors short, since the longer they get, the more apt they are to break. If you create very specific selectors you will often find that you need to duplicate chunks of your CSS to apply the same rules to another element. Try to reduce nesting to two or three levels deep and remove as many location-based selectors as possible. Usually, these longer selectors are overkill and unnecessary. If you do find that you need to use a really specific selector, refactor it into a new manageable class.

Use Shorthand Properties & Values

Do this to increase readability. If your shorthand font: property is not more readable, then it is not better. Shorthand properties can also introduce undesired resetting of properties (sometimes unrelated) back to their initial value.

/* bulky, but clear */
p {
  font-family: sans-serif;
  font-size: 1.6rem;
  font-style: italic;
  font-weight: 400;
  line-height: 1.5;
}

/* cleaner, but not necessarily clearer */
p {
  font: sans-serif 1.6rem italic 400 1.5;
}

Drop Units from Zero Values

/* BAD */
margin: 0px 10px 0px 0px;
/* GOOD */
margin: 0 10px 0 0;

Use The Right Measurement For The Right Job

I have read many different pieces of advice on this. Use rem for everything, use em for everything, don't use px ever, use 60ch as the width of a page, etc. I do believe that using rem for everything may cause blowout of a page when zooming in a lot for accessibility, due to enormous borders, margin, etc. This is some advice I found online that seems to make sense:

  • px for border widths, box shadows, etc. (decoration)
  • rem or em for font sizes (rem for modular component-based layouts)
  • vw/vh/% for layout and display specific rules, since they change with the browser size
  • rem for font sizes and for margins and padding
  • ch for things like paragraph text widths or sizing containers that will hold monospace fonts (50-70 chars wide is a common human-readable width, so aim for 60ch in this case)
  • em for media queries (e.g. max-width: 40em is equal to 640px with a font-size of 16px, but will scale if user has it set differently)
  • in/cm/mm for print queries

Group & Align Vendor Prefixes

Keep them together and add whitespace to make the values aligned.

When using vendor prefixes we need to make sure to place an unprefixed version of our property and value last, after any prefixed versions, to ensure the most desired setting loads last if possible.

div {
  background: -webkit-linear-gradient(#a1d3b0, #f6f1d3);
  background:    -moz-linear-gradient(#a1d3b0, #f6f1d3);
  background:         linear-gradient(#a1d3b0, #f6f1d3);
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}

Modularize Styles for Reuse

Refactor names to fit their purpose and reduce hacky "fixes" to shoehorn stuff in to other class rules. Keep your code DRY!

Break large stylesheets into multiple smaller ones

In particular in cases where you have very different styles for distinct parts of the site, you might want to have a stylesheet that includes all the global rules and then smaller ones that include the specific rules needed for those sections. You can link to multiple stylesheets from one page, and the normal rules of the cascade apply, with rules in stylesheets linked later coming after rules in stylesheets linked earlier.

Structure / Formatting

Create logical sections in your stylesheet

Using the ideas from 7-1 Sass architecture, we can create an organization that will allow us to organize our styles in a way that allows for a logical hierarchical cascade and easy management. The 7 sections are abstracts, vendors, base, layout, components, pages, and themes.

Media Queries

Note: media queries don't have an exact space so far as I have found, but there are a couple approaches:

  • for maintenance and modularity's sake, keeping them with the rest of the relevant rules feels logical.
  • for the cascade, putting them at the end of their respective file before the utilities allows them to take priority over rules with similar specificity.
.grid { 
  ...
}

@media (screen) and (max-width: 800px) {
  .grid {
    ...
  }
}

Abstracts

Abstracts are code that does not output CSS (variables, and in Sass, functions and mixins).

/* || VARIABLES */

:root {
  --bg-color: #FFF;
  --text-color-primary: #000;
  --text-color-secondary: #888;
  --link-color: #F00;

  --font-sans: Helvetica, sans-serif;
  --font-serif: Times, sans-serif;

  --text-spacing-wide: .5px;
}

Vendors

This includes any third party stylesheets, like Bootstrap, or font imports like Google Fonts.

/* || VENDORS */

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap');

Base

Basic definitions like animations, default styles, typography, resets/normalizers and utilities like classes for center text, margin bottom, etc. It is a good idea to have all of the common styling early in the stylesheet so that all of these styles will generally apply unless you do something special with that element.

/* || BASE STYLES */

/* | RESETS */

html {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
  margin: 0;
  padding: 0;
}

/* | ANIMATIONS */

@keyframes animationName {
  ...
}

/* | TYPOGRAPHY */

html {
  color: var(--text-color-primary);
  font-family: Helvetica, sans-serif;
}

h1, h2, h3, h4 { 
  ... 
}

a {
  ...
}

/* | UTILITIES */

.nobullets {
  list-style: none;
  margin: 0;
  padding: 0;
}

Layout

This could have styles for the main parts of the site (header, footer, navigation, sidebar, etc.), the grid system, or even CSS styles for all the forms. These are the "macro" components.

/* || LAYOUT */

/* | HEADER */

.header {
  ...
}

/* | FOOTER */

.footer {
  ...
}

/* | GRID */

.grid {
  ...
}

Components

Modules that will be reused often throughout the project (buttons, forms, media boxes, etc.). These are the "micro" components in comparison to the layout.

/* || COMPONENTS */

/* | BUTTON */

.button {
  ...
}

  .button--white {
    ...
  }

  .button--magenta {
    ...
  }

Page

These are styles specific only to the specific page you are on. Many times a home page will have different layouts than the blog or the about page. This is where you would put the styles for that specific page.

For a single stylesheet, this will likely be just another section as opposed to another file.

Theme

For large projects, this allows a plug-and-play way to change the theme of your site. Usually this is not used on smaller applications.

Example CSS Skeleton / Template

/* || ABSTRACTS */

/* || VENDORS */

/* || BASE */

/* || LAYOUT */

/* || COMPONENTS */

/* || PAGES */

/* || THEMES */

References

  1. https://learn.shayhowe.com/html-css/writing-your-best-code/
  2. https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Organizing
  3. https://www.reddit.com/r/css/comments/kzkthl/what_units_do_you_use_px_vw_and_vh_em_rem/
  4. https://meyerweb.com/eric/thoughts/2018/06/28/what-is-the-css-ch-unit/
  5. https://github.com/HugoGiraudel/sass-boilerplate/tree/master/stylesheets
  6. https://www.learnhowtoprogram.com/user-interfaces/building-layouts-preprocessors/7-1-sass-architecture
  7. https://www.freecodecamp.org/news/css-media-queries-breakpoints-media-types-standard-resolutions-and-more/

Last modified: 202107020528

Gradients (CSS)

How to create and use linear gradients in CSS.

Background or Image

/*
linear-gradient(
  {direction},                      `to left top`, `45deg`, `0.25turn`
  {starting color}
    {full color starting position}  `0`, `33%`
    {full color ending position},   `33%`, `50%`
  ...more colors
) 
*/

.gradient {
  background-image: linear-gradient(to right, $color-primary-light, $color-primary-dark);
}

You can make an immediate switch between colors by setting starting and ending positions at the same value. This example goes to the bottom right from 0%-50% with white and then from 50% to 100% with orange.

.selector {
  background-image: linear-gradient(to right bottom, white 50%, orange 50%);
}

Text

h1.gradient-text {
  /* Create the bg gradient */
  background-image: linear-gradient(to right, $color-primary-light, $color-primary-dark);
  /* Confine gradient area to width of content */
  display: inline-block;
  /* Clip the bg gradient to the text area */
  -webkit-background-clip: text;
          background-clip: text;
  /* Allow gradient to show through text area */
  color: transparent;
}

References

  1. https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient()

Last modified: 202107020508

Assembly

Assembly is an extremely low-level human-readable language that has a strong relation between the code and the corresponding machine code.

Compilation and Linking

For more specifics, visit the OSX and Windows assembly pages.

You will first need a program to compile your assembly into machine code. Most common is the program nasm for Unix systems and masm for Windows systems.

After you have written your code, you will need to assemble your code, translating it from the human readable assembly language into a file object.

You will then need to link your newly created output file. This will pull all the needed libraries into a single executable.

Syntax and Keywords

Operators

Command Effect
mov x, y xy
and x, y xx & y
or x, y xx | y
xor x, y xx ^ y
add x, y xx + y
sub x, y xxy
mul x EAXEAX * x
div x EAXEAX ÷ x
inc x xx + 1
dec x xx – 1

Instructions

Command Effect
cmp x, y Set the
jmp label When this line is reached, jump to the line labeled label
je label / jz label When ZF is 0, jump to label
jne label / jnz label When ZF is NOT 0, jump to label

Pseudo-instructions

Command Effect
syscall Invoke an operating system routine
db A pseudo-instruction that declares bytes that will be in memory when the program runs

section

A section is an assembler directive that tells the assembler what kind of code follows. Generally, you put code in a section called .text and your constant data in a section called .data.

Registers

32-Bit General Purpose

Address Name Description
EAX Accumulator Register calculations for operations and results data
EBX Base Register pointer to data in the DS segment
ECX Count Register counter for string and loop operations
EDX Data Register input/output pointer
ESI Source Index source pointer for string operations
EDI Destination Index destination pointer for string operations
ESP Stack Pointer stack pointer, should not be used
EBP Base Pointer pointer to data on the stack

16-Bit Segment

Address Name Description
CS Code Segment where instructions being executed are stored
DS, ES, FS, GS Data Segment data segment
SS Stack Segment where the stack for the current program is stored

32-Bit Other

Address Name Description
EFLAGS Code Segment status, control, and system flags
EIP Instruction Pointer offset for the next instruction to be executed

Flags

Carry Flag (CF)

The carry flag is set to 1 (true) when the second operand of an operation is smaller than the first. For example if you cmp 2 1, the result will be a CF of 1 (true), since 1 - 2 goes negative, meaning that the first operand is larger than the first.

Overflow Flag (OF)

The overflow flag will be set to 1 (true) if the operation overflows beyond the bounds of the integers and their storage. This could happen if you are dealing with numbers that go beyond the boundaries involved (e.g. adding two numbers that go above 256 with an 8-bit unsigned integer, or adding two 8-bit unsigned integers that go beyond 128).

Sign Flag (SF)

The sign flag will be set to 1 (true) after an arithmetic operation when the result is negative.

Zero Flag (ZF)

The zero flag is set after an arithmetic operation and will have a value of 1 (true) when the result is zero, and 0 (false) when the result is not zero.

Stack

The stack is used to invoke a function or as temporary storage by pushing parameters in last in first out to be utilized by the function.

This will push the number 3 onto the stack and then write it to the EAX register.

push 3
pop eax
ret

This will push three values to the stack in reverse order of what the function expects, because LIFO, and then invokes the function, which will use those values.

push [var] ; Push last parameter first
push 216   ; Push the second parameter
push eax   ; Push first parameter last

call _myFunc ; Call the function (assume C naming)

add esp, 12  ; Flush the three 4 byte values on the stack by 
      ; adding 12 to the stack pointer

References

  1. https://www.tutorialspoint.com/assembly_programming/assembly_basic_syntax.htm
  2. https://www.youtube.com/watch?v=qhkEOyK1ek0
  3. https://www.youtube.com/watch?v=wLXIWKUWpSs
  4. https://doc.lagout.org/operating%20system%20/Windows/winasmtut.pdf
  5. https://www.cs.uaf.edu/2015/fall/cs301/lecture/09_16_stack.html
  6. https://www.cs.virginia.edu/~evans/cs216/guides/x86.html
  7. https://www.hellboundhackers.org/articles/read-article.php?article_id=729

Backlinks:

Last modified: 202107112229

Assembly (Windows)

Assembly on Windows utilizes masm, Microsoft's proprietary assembler and linker.

Compilation, Linking, and Execution

Compiler

You will first need masm to compile your assembly into machine code. masm can be installed via the MASM32 SDK.

Your First Program

Create a file called hello_world.asm. Copy this into it's contents:

.386                  ; Tell assembler to use the 386 instruction set
.model flat, stdcall            ; Specify the flat memory model and use stdcall to pass parameters RtoL
option casemap :none          ; Force case sensitivity

include \masm32\include\windows.inc    ; Include Win32 API constants and defs
include \masm32\include\kernel32.inc   ; Include ExitProcess
include \masm32\include\masm32.inc     ; Include StdOut

includelib \masm32\lib\kernel32.lib   ; The libraries necessary for the above includes to function
includelib \masm32\lib\masm32.lib

.data                   ; The section for all initialized data
  HelloWorld db "Hello World!", 0    ; definebyte HelloWorld to equal Hello World! plus a NUL char

.code                    ; Starting point for program code
start:                   ; All code must live between this and end start
  invoke StdOut, addr HelloWorld    ; Run function StdOut with address of HelloWorld as the param 
  invoke ExitProcess, 0         ; Invoke ExitProcess with 0 (success) as the parameter

end start 

Assembling Your Code

Assembling your code will translate it from the human readable assembly language into a file object. The following command will run masm and create output hello_world.obj.

\masm32\bin\ml /c /Zd /coff hello_world.asm

Linking Your File

Linking your newly created output file will pull all the needed libraries into a single executable. The following command will run Link, the masmlinker, and finish the creation of your executable.

\masm32\bin\Link /SUBSYSTEM:CONSOLE hello_world.obj

Executing Your File

hello_world.exe
Hello, World!

Running hello_world.exe in the command line should result in the message being displayed.

masm-specific Syntax

invoke

invoke is a special function in masm to call functions without having to push parameters beforehand.

invoke SendMessage, [hWnd], WM_CLOSE, 0, 0

; equivalent to

push 0
push 0
push WM_CLOSE
push [hWnd]
call [SendMessage]

References

  1. https://doc.lagout.org/operating%20system%20/Windows/winasmtut.pdf
  2. https://masm32.com/

Backlinks:

Last modified: 202107112140

Assembly (Unix)

Assembly on Unix is largely the same between MacOS and Linux computers.

Compilation, Linking, and Execution

Compiler

You will first need a program to compile your assembly into machine code. Most common is the program nasm, which can be installed on OSX using homebrew with brew install nasm.

Your First Program

Create a file called hello_world.asm. Copy this into it's contents:

; ----------------------------------------------------------------------------------------
; Writes "Hello, World" to the console using only system calls. Runs on 64-bit macOS only.
; ----------------------------------------------------------------------------------------

        global    start                   ; nasm-specific way to define a location for the linker

        section   .text                   ; The .text section holds all the instructions for the 
                                          ; assembler to execute.
start:                                ; The label that is referenced in the above global call
        mov       rax, 0x02000004         ; system call for write (copy param Y into param X)
        mov       rdi, 1                  ; file handle 1 is stdout
        mov       rsi, message            ; address of string to output
        mov       rdx, 13                 ; number of bytes (message is 13 chars long)
        syscall                           ; invoke operating system to do the write
        mov       rax, 0x02000001         ; system call for exit
        xor       rdi, rdi                ; exit code 0
        syscall                           ; invoke operating system to exit

        section   .data                   ; The .data section contains constants
message:                              ; The label referenced above
        db        "Hello, World", 10      ; note the newline at the end

Assembling Your Code

Assembling your code will translate it from the human readable assembly language into a file object. The following bash command will run nasm using the Mach-O 64bit object -file notation format used by the 64-bit version of MacOS and create -output hello_world.o.

$ nasm -f macho64 hello_world.asm -o hello_world.o

Linking Your File

Linking your newly created output file will pull all the needed libraries into a single executable. The following bash command will run ld, the GNU linker, and finish the creation of your executable.

$ ld -macosx_version_min 10.7.0 hello_world.o -o hello_world

The -macosx_version_min flag is added to remove the warning that is present without it. I read that it still builds fine without it, but that has not been true in my experience.

Executing Your File

$ ./hello_world
Hello, World

Running ./hello_world in bash should result in the message being displayed.

References

  1. https://medium.com/@thisura1998/hello-world-assembly-program-on-macos-mojave-d5d65f0ce7c6
  2. https://cs.lmu.edu/~ray/notes/nasmtutorial/
  3. https://stackoverflow.com/questions/52830484/nasm-cant-link-object-file-with-ld-on-macos-mojave
  4. https://www.nasm.us/doc/
  5. https://www.youtube.com/watch?v=qhkEOyK1ek0
  6. https://www.youtube.com/watch?v=wLXIWKUWpSs
  7. https://github.com/camsaul/hello_world_x86_64_asm_os_x
  8. http://zathras.de/angelweb/blog-learn-nasm-on-os-x.htm
  9. http://caswenson.com/2009_09_26_assembly_language_programming_under_os_x_with_nasm
  10. https://lord.io/assembly-on-osx/
  11. https://orangejuiceliberationfront.com/intel-assembler-on-mac-os-x/

Backlinks:

Last modified: 202107112052

Stack (Programming)

There's currently nothing here.

Backlinks:

Last modified:

Canvas

The Canvas API provides a means for drawing graphics via JavaScript and the HTML element.

Initialization

To start using the canvas, put the canvas element in your webpage HTML, along with a width or height in pixels. Fallback content goes in between the opening and closing tag.

<canvas id="canvas-name" width="150" height="150"></canvas>

The canvas is initially blank and then needs to be accessed, with the new context assigned to a variable. This variable will become the way to draw on the canvas.

var canvas = document.getElementById('canvas-name');
var ctx = canvas.getContext('2d');

Drawing

Canvas only supports rectangles and paths.

Rectangles

ctx.fillRect(x, y, width, height)   // Draws a filled rectangle.
ctx.strokeRect(x, y, width, height) // Draws a rectangular outline.
ctx.clearRect(x, y, width, height)  // Clears the specified rectangular area, making it fully transparent.

Paths

From MDN:

A path is a list of points, connected by segments of lines that can be of different shapes, curved or not, of different width and of different color. A path, or even a subpath, can be closed. To make shapes using paths, we take some extra steps:

  1. First, you create the path with beginPath()
  2. Then you use drawing commands to draw into the path
  3. Once the path has been created, you can stroke or fill the path to render it with closePath()
ctx.beginPath() // Creates a new path. Once created, future drawing commands are directed into the path and used to build the path up.
ctx.closePath() // Adds a straight line to the path, going to the start of the current sub-path.
ctx.stroke()    // Draws the shape by stroking its outline.
ctx.fill()      // Draws a solid shape by filling the path's content area.

Path Methods

moveTo(x,y) moves the pen without recording it as a path to be drawn or filled.

lineTo(x,y) should be used to draw straight lines.

arc(x, y, radius, startAngle, anticlockwise) will draw an arc centered at x, y.

arcTo() is often used to make rounded corners https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arcTo

quadraticCurveTo(cp1x, cp1y, x, y) and bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) are also good for [rounded shapes](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D#paths.

References

Last modified: 202107020533

Web Fonts (HTML)

To import a font from Google Fonts, you can copy the font(s) URL from the Google Fonts library and then paste it in your HTML. For this challenge, we'll import the Lobster font. To do this, copy the following code snippet and paste it into the top of your code editor (before the opening style element):

<link href="https://fonts.googleapis.com/css?family=Lobster" rel="stylesheet" type="text/css">

Now you can use the Lobster font in your CSS by using Lobster as the FAMILY_NAME as in the following example:

font-family: FAMILY_NAME, GENERIC_NAME;

The GENERIC_NAME is optional, and is a fallback font in case the other specified font is not available.

References:

  1. https://www.freecodecamp.org/learn/responsive-web-design/basic-css/import-a-google-font

Last modified: 202107020536

Anchor Tags (HTML)

Download

Using the download attribute will instruct the browser to download the file enclosed in the value of the download attr. The value is optional.

<a href="file.pdf" download>Download Here</a>
<a href="file.pdf" download="new-filename.pdf">Download Here</a>

So far I have not seen the attribute force a download of a file, but I have seen it change the download name of the file re: things like PDFs.

References

  1. https://stackoverflow.com/questions/23825871/how-to-force-a-download-file-prompt-instead-of-displaying-it-in-browser-with-htm
  2. https://www.w3schools.com/tags/att_a_download.asp

Last modified: 202107020531

Semantic HTML

HTML without any styling or functionality should be readable and the user should easily be able to discern context about the content.

Headings

Headings should be used for semantics only, not for font sizing (HTML for structure, CSS for styling).

Heading information can be used by user agents to construct a table of contents for a document automatically.

Use only one <h1> per page or view. It should concisely describe the overall purpose of the content. Using more than one <h1> will not result in an error, but is not considered a best practice. Using only one <h1> is beneficial for screenreader users, and SEO. Avoid skipping heading levels: always start from <h1>, followed by <h2> and so on.

References

  1. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements

Backlinks:

Last modified: 202107020535

HTML Tables

The basics of HTML5 tables and semantic HTML tables.

Summary of All Elements

<table summary="Extended summary for accessibility and screen readers">
  <!-- caption or title -->
  <caption>Caption</caption>
  <thead>
    <!-- row -->
    <tr> 
      <!-- col header -->
      <th abbr="Shortened heading for accessibility/screen readers" scope="col">Header 1</th>
      <th abbr="Shortened heading for accessibility/screen readers" scope="col">Header 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <!-- row header -->
      <th abbr="Shortened heading for accessibility/screen readers" scope="row">Row Header</th>
      <!-- table data -->
      <td>Some data</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>Footer data 1</td>
      <td>Footer data 2</td>
    </tr>
  </tfoot>
</table>

More complex tables with empty cells/row headers have added accessibility needs, like scope="col/row" depending on what the header organizing.

Merging Cells

The colspan attribute is used to span a single cell across multiple columns within a table, while the rowspan attribute is used to span a single cell across multiple rows. Each attribute accepts an integer value that indicates the number of cells to span across, with 1 being the default value.

<tr rowspan="2">
   <td colspan="3">...</td>
</tr>

This can't be done using CSS. It must be done using inline styles.

Borders

The border-collapse property determines a table’s border model. There are three values for the border-collapse property: collapse, separate, and inherit. By default, the border-collapse property value is separate, meaning that all of the different borders will stack up next to one another, as described above. The collapse value, on the other hand, condenses the borders into one, choosing the table cell as the primary border.

The border-spacing property may accept two length values: the first value for horizontal spacing and the second value for vertical spacing.

References

  1. https://learn.shayhowe.com/html-css/organizing-data-with-tables/
  2. https://www.456bereastreet.com/archive/200410/bring_on_the_tables/

Last modified: 202107020535

Emmet

There's currently nothing here.

Backlinks:

Last modified:

Sublime Text

Sublime Text is an application made for software development.

Command Line Shortcut

To create a symlink in bash that will allow you to open any folder in Sublime Text:

echo 'export PATH="/Applications/Sublime Text.app/Contents/SharedSupport/bin:$PATH"' >> ~/.bash_profile
// or
echo 'export PATH="/Applications/Sublime Text.app/Contents/SharedSupport/bin:$PATH"' >> ~/.zprofile

Now you can just type subl . in a given folder, a la code . in Visual Studio Code

Troubleshooting Errors

Autocompletion/Snippets

  1. Open the console (View > Show Console or ctrl + ` on OSX).
  2. In the console, enter in sublime.log_commands(True).
  3. Do what you need to recreate the issue. Immediately after triggering the unwanted behavior, document what you think is causing it that is in the console. In my case it was command: insert_snippet {"contents": ":$0;"}.
  4. Depending on which syntax you are in, or which plugin is listed/suspected, use the command palette to View Package File and type in the syntax/plugin. This will show files that are hidden, as well, which makes diagnosing issues with default plugins/syntaxes much easier. In my case this was in the keymap file.
  5. Once you find a possible file, open it. Save As in the Packages directory under a new folder called the name of the plugin or syntax. e.g. for the Sass plugin/syntax, I created a folder in Packages called Sass and saved a copy of the Default.sublime-keymap file there, which included my additions. You can find more on overriding packages here.
  6. In my case, I copied the old rule over and changed the {"contents": ":$0;"} object to {"contents": ":$0"}, which allowed the colon to be typed without adding any additional characters.

Syntax Highlighting

Packages in Sublime Text are interdependent on each other and many of the default packages are inferior to third-party (e.g. Babel over Javascript). When nested syntaxes are not cooperating, in this example Pug's Javascript syntax, you can Disable Package > Javascript and install Babel and this will cause Pug to correctly highlight conditionals and the succeeding code.

References

  1. https://milofultz.com/2021/03/06/sublime-keymap
  2. https://stackoverflow.com/questions/59635627/how-to-override-sublime-text-3-packages-css3-completion-syntax
  3. https://www.sublimetext.com/docs/command_line.html#mac

Backlinks:

Last modified: 202107020503

Pug

Pug is a templating engine for HTML that allows you to write a simpler more condense webpage, as well as integrating Javascript to dynamically generate pages.

Getting Started

Install it using NPM: npm i -g pug-cli. You can compile a Pug file directly, or by watching the file and it's dependencies for changes.

# compile the single file
pug filename.pug -o ./outputfolder
# watch the file and its dependencies for changes and compile on change
pug -w filename.pug -o ./outputfolder

Syntax

Writing HTML in Pug is very similar to Emmet shorthand/selectors in CSS.

element#id.class(attr="value" foo="bar") innerText

header#header.header.header__wrapper
  .header__logo
    span
      img.header__logo-img(src="..." alt="Logo")
      |  Some text!
  h1 Company Name

//- outputs

//- <header id="header" class="header header__wrapper">
//-   <div class="header__logo">
//-     <span><img src="..." alt="Logo" /> Some text!</span>
//-   </div>
//-   <h1>Company Name</h1>
//- </header>

Comments

// This comment will appear in the HTML

//- This is a silent comment

//-
  Nesting inside a comment creates
  a comment block

Javascript

Any line that starts with a hyphen or anything that follows an equals sign in an attribute list can be valid Javascript.

- var num = 6;
- var name = "John Smith";

h1(data-name= name.replace(/\s/, '.').toLowerCase() )= `This guy is probably ${num} feet tall!`

//- outputs
//- <h1 data-name="john.smith">This guy is probably 6 feet tall!</h1>

Inline

h1: span.header Yeah!

//- Outputs
//- <h1><span class="header">Yeah!</span></h1>

Multiline

p.
  This text can be broken 
  up on multiple lines

//- outputs
//- <p>This text can be broken
//-     up on multiple lines</p>

script.
  console.log('or here');
  // This works too.

Self-Closing Tags

hr 
//- outputs <hr/>

foo/
//- outputs <foo/>

Imports / Include

Pug allows import of HTML directly as well as Pug files.

include filename.pug
include another.html

Variables

Variables in Pug are defined as they are in Javascript and should be preceded by a hyphen. Multiline variable definitions are done by starting a line with a hyphen, leaving no whitespace, and continuing indented on the next line. As long as the indentation remains, you will be in "Javascript land".

- var location = 'russia';
-
  var obj = {
    thing: "one",
    otherThing: "two",
  }

p= location
span(class= obj.thing) OK

//- outputs 

//- <p>russia</p>
//- <span class="one">OK</span>

Conditionals

- var location = 'russia';
- var cold = true;

if location === 'los-angeles'
  p Party!
else if location === 'mexico'
  p MORE Party!
else if cold
  p cold party
else
  p no party

span= cold ? "Brr!" : "*panting*"

//- outputs 
//- <p>cold party</p>
//- <span>Brr!</span>

Iteration

Arrays

- var items = ['candy', 'cake', 'ice cream'];

each item in items
  p.item(id= item.replace(' ', '-'))= item.toUpperCase()

//- outputs
//- <p id="candy" class="item">CANDY</p>
//- <p id="cake" class="item">CAKE</p>
//- <p id="ice-cream" class="item">ICE CREAM</p>

Objects

- 
  var people = {
    'John': 'Johnson',
    'Ashley': 'Ashtown',
  };

each last, first in people
  p= first + ' ' + last

//- outputs
//- <p>John Johnson</p>
//- <p>Ashley Ashtown</p>

Sublime Text Syntax

Packages in Sublime Text are interdependent on each other and many of the default packages are inferior to third-party (e.g. Babel over Javascript). When Pug's Javascript syntax is not cooperating or popping to allow Pug's syntax to take over again, you can Disable Package > Javascript and install Babel and this will cause Pug to correctly highlight conditionals and the succeeding code.

References

  1. https://www.sitepoint.com/a-beginners-guide-to-pug/
  2. https://pughtml.com/
  3. https://devhints.io/pug
  4. https://pugjs.org/language/conditionals.html
  5. https://pugjs.org/language/includes.html
  6. https://cssdeck.com/labs/learning-the-jade-templating-engine-syntax

Backlinks:

Last modified: 202107152002

HTML Forms

The basics of HTML forms, semantic HTML forms, and validation.

Form Element

The action attribute that defines the action to be done upon submission as an address or href. The method is the HTTP method to use in completing the action.

Input Types

Input

  • Pre-HTML5 input types:
    • button
    • checkbox
    • file
    • hidden
    • image
    • password
    • radio
    • reset
    • submit
    • text
  • HTML5 input types:
    • color
    • date
    • datetime
    • email
    • month
    • number
    • range
    • search
    • tel
    • time
    • url
    • week

These values were added to provide clearer semantic meaning for inputs as well as to provide better controls for users. Should a browser not understand one of these HTML5 type attribute values, it will automatically fall back to the text attribute value.

Label

The label element provides a label for an input element, with its for="" attribute referencing the id attribute of the element it is to label.

<input type="text" id="thing">
<label for="thing">Thing!</label>

Select

The size attribute chooses how many choices are visible at a time. The boolean attribute multiple, when added to the <select> element for a standard drop-down list, allows a user to choose more than one option from the list at a time.

<label for="things">Things!</label>
<select id="things" name="things" multiple>
  <option value="thing1">Thing 1</option>
  <option value="thing2" selected>Thing 2</option>
</select>

Textarea

A textarea has rows and columns attributes to determine the size, but can be done more efficiently with CSS styling.

Button

Always include type="button" for compatability across browsers.

<button type="button">Click Here</button>

Radio Buttons and Checkboxes

A radio button and checkbox input element can be checked by default by adding the checked boolean attribute to the input field. This requires them being within a form element; otherwise they will not select correctly in all browsers.

Fieldsets and Legends

Fieldsets group form controls and labels into organized sections. Much like a <section> or other structural element, the <fieldset> is a block-level element that wraps related elements, specifically within a <form> element, for better organization. The <legend> element wraps text describing the form controls that fall within the fieldset. The markup should include the <legend> element directly after the opening <fieldset> tag.

<form action="">
  <fieldset>
    <legend>Thing Description:</legend>
    <label for="things">Things!</label>
    <select id="things" name="things" multiple>
      <option value="thing1">Thing 1</option>
      <option value="thing2" selected>Thing 2</option>
    </select>
  </fieldset>
</form>

Field Validation

Input

Use the correct input type (text, email, password, etc.)

The pattern attribute is used to specify a regular expression and the field value must match this pattern. This attribute can be used with input types like text, password, email, url, tel and search. Validation occurs upon submission.

<!-- Should match if five numbers from 1 to 4 appear in a row -->
<input type="text" pattern="[1-4]{5}">

A required attribute indicates that a value must be specified for the input element.

<input type="text" required>

maxlength is an integer value that specifies the maximum number of characters allowed for a particular input field.

<input type="text" maxlength="20">

min & max attributes specify the lower and upper limit respectively for an input element.

<input type="number" min="1" max="5">

References

  1. https://www.w3schools.com/html/html_form_elements.asp
  2. https://stackoverflow.com/questions/3606657/radio-buttons-checked-attribute-not-working

Last modified: 202107020533

Text Compression (Server)

Text compression minifies and zips files on build or on client side rendering of your web page. Using this on your deployed webpage can save significant time in page downloads and lead to better user retention.

Implementation

To accomplish client-side rendering, you will need to implement the compression on the building of your pages (in this case, using Webpack) as well as on your server (Express). This example is for a React project using Webpack and Express.

Webpack

First, install compression-webpack-plugin and add it to your webpack.config.js file:

module.exports = {
  ...
  plugins: [
    new CompressionPlugin({
      algorithm: 'gzip',
      test: /\.(js|css)$/i,
    }),
  ],
  ...
};

This will use GZIP to compress all JS and CSS files in your project.

Express

Similar to Express's app.use(express.static(...)), this will allow Express to serve the GZIP files to the user. You need to install express-static-gzip and then add this to your server JS file:

var express = require("express");
var expressStaticGzip = require("express-static-gzip");
var app = express();

app.use("/", expressStaticGzip("/my/rootFolder/"));

On Your Server

On your server, add/merge your new code, npm i all the new dependencies, restart any PM2 instances and NGINX, and away you go!

References

  1. https://developers.google.com/speed/pagespeed/insights/
  2. https://stackoverflow.com/questions/57504666/enable-text-compression-using-react-webpack-and-apache
  3. https://stackoverflow.com/questions/50442039/compression-webpack-plugin

Last modified: 202107010334

Visual Studio Code

Visual Studio Code/Codium is an open-source application developed by Microsoft for software and code development.

Extensions Missing

If an extension is found on VS Code but not on VS Codium, it can still be installed by sideloading it as a VSIX. "You'll have to sideload that extension since the marketplace that VS Codium uses is OpenVSX which hosts only open source extensions"[1].

You can download it on the website and in the "Extensions" pane of VS Codium, click the dots up top and choose "Install VSIX".

References:

  1. https://www.reddit.com/r/vscode/comments/lt8y62/live_share_missing_from_extension_marketplace/
  2. Live Share

Backlinks:

Last modified: 202107020502

Fetch API

Fetch API is a part of vanilla Javascript that does HTTP requests.

Usage

The syntax for fetch is fetch('URL'). fetch() ALWAYS returns promises. These promises will be fulfilled when the data is finished loading, and can be accessed with .then(function (response) { ... }). Within .then, you can resolve this promise with .json(), .text(), or .blob(), which all return their own promise. Errors are handled through a .catch(function (response) { ... }).

fetch('http://web.site')
  .then(function (response) {
    // response is a Promise, so it will be resolved within this function
    return response.json();
    // response.json is *also* a Promise
  }).then(function (json) {
    // do thing with JSON response
  }).catch(function (error) {
    console.log(error);
  });

With async/await

If you encapsulate the fetch call within a function, you can declare that function as an async function and make the calls inside the function await. Because it's an async function, it will also return a promise, which can be handled by .then and .catch.

var getJSON = async function () {
  var response = await fetch('http://web.site');
  var json = await response.json();
  // do thing with JSON response
};

getJSON().catch(function (error) {
  console.log(error);
});

References

  1. https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
  2. https://www.youtube.com/watch?v=tc8DU14qX6I
  3. https://www.youtube.com/watch?v=RfMkdvN-23o

Backlinks:

Last modified: 202107020539

Arrays (Javascript)

Arrays in Javascript have many specific methods for modification and analysis. Some are cunfusiong or hard to recall.

Modification

sort

The sort function can work with or without a sorting function that sorts in place. Without, it will simply convert every value into a string and compare via Unicode point value. With, it follows this formula: .sort(compareFunction).

From MDN:

If compareFunction(a, b) returns a value > than 0, sort b before a. If compareFunction(a, b) returns a value ≤ 0, leave a and b in the same order.

An example compare function:

const array = [3,2,4,1];

const compareFunction = (a, b) => {
  if (a < b) {
    // leave a before b
    return -1;
  } else if (a > b) {
    // place b before a
    return 1;
  } else { // a === b
    // leave a before b
    return 0;
  }
};

array.sort(compareFunction); // array now equals [1,2,3,4]

splice

Splice works for both removal and insertion of array elements. Splice operates in place and will return whatever elements were spliced from the array.

splice(start, deleteCount, [item, ...])

let array = [1,2,3,4];
array.splice(1); // returns [2,3,4]; array now equals [1]

array = [1,2,3,4];
array.splice(1,1); // returns [2]; array now equals [1,3,4]

array = [1,2,3,4];
array.splice(1,1,17); // returns [2]; array now equals [1,17,3,4]

Last modified: 202107171713

MongoDB

MongoDB is a NoSQL database management system using documents similar to JSON.

Getting Started

This will start a new project using your local server and mongoose via node.

Local Machine

Install MongoDB using brew services install mongodb-community. Once installed, you can start your local server using brew services start mongodb-community (Be sure to stop the server when completed with your work using brew services stop mongodb-community).

In the terminal, start the mongo shell: mongo.

Database

Creating a new database is done when a query is made.

Node

Create a new folder and initialize a new node project using npm: npm init -y. Then install npm i mongoose.

Create a new file called server.js and copy this into the contents:

const mongoose = require('mongoose');                // import Mongoose
mongoose.connect('mongodb://localhost:27017/test', { // create connection to localhost
  useNewUrlParser: true, 
  useUnifiedTopology: true
});

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {                            // Inside here is where the action happens
  const kittySchema = new mongoose.Schema({
    name: String
  });
  const Cat = mongoose.model('Cat', { name: String }); // Create schema for collection

  const kitty = new Cat({ name: 'Zildjian' });         // Create a new document of Cat
  console.log(kitty.name);                             // 'Zildjian'
  kitty.save()
    .then(() => console.log('meow'));                   // Save the new document in the Cat collection
});

In the terminal, run node server.js. This should log 'Zildjian' along with meow.

Indexes

If your collection does not have an index, your query could take a very long time, as it will have to scan every single document within your collection and analyze it to see if it matches your query.

Data Import

Use mongoimport to bring in Extended JSON, CSV, or TSV files to your Mongo database. First, start up your database, and then use mongoimport in the command line:

#             use the PetHotel db      use header line as field names
$ mongoimport --db=PetHotel --type=csv --headerline --file=pets.csv

# If no header line is availabe:       list them out after the --fields option
$ mongoimport --db=PetHotel --type=csv --fields=_id,name,type --file=pets.csv

Syntax

Command Effect
show dbs List all databases on the given server
use database_name Enter into database_name, preparing to query.
db.dropDatabase() Delete the selected database
show collections / show tables List all collections/tables in the selected database.
db.collection_name.find() Return all documents in collection collection_name.
db.people.find({name: 'John'}) Return all documents in people whose name is John.
db.people.insert({name: 'John', age: 40}) Create a document in people (note: if a new collection is selected via use, this will create the new collection)

References

  1. https://www.mongodb.com/basics/examples
  2. https://www.mongodb.com/basics/create-database
  3. https://docs.mongodb.com/manual/core/databases-and-collections/
  4. https://mongoosejs.com/
  5. https://www.npmjs.com/package/mongoose
  6. https://docs.mongodb.com/manual/core/aggregation-pipeline/
  7. https://database.guide/import-a-csv-file-into-mongodb-with-mongoimport/
  8. https://docs.mongodb.com/manual/indexes/

Backlinks:

Last modified: 202107200304

Mongoose (Javascript)

Mongoose is an NPM package that allows a simple and schema'd Javascript entrypoint to your Mongo database.

Basics

Setup

Install mongoose: npm i mongoose and ensure your database is running.

Project

Create a new file called server.js and put this within.

// Initilize database

const mongoose = require("mongoose");
const dbName = "test";
mongoose.connect(`mongodb://localhost:27017/${dbName}`, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

// Create test schema

const testSchema = new mongoose.Schema({
  name: String,
  age: Number,
  friends: [String],
});

// Create a model from your schema

// this first param is the name of your collection in your test database
const Test = mongoose.model("test", testSchema);

// Connect to database

const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", () => {
  console.log(`Mongoose DB "${dbName}" initialized\n`)
});

This will have created your basics. You can now start creating queries, inserting items into your database, etc.

Troubleshooting

Return Object

The return of a query is not a plain Javascript object and will show weird behavior when trying to add to/remove from/modify it. If you want a plain Javascript object in return, you can use .lean() within your chain to cast it.

References

  1. https://mongoosejs.com/

Last modified: 202107200301

Testing (Javascript)

Javascript provides many options to test your code via timing, assertions, and frameworks.

Time

Simplest Timer

console.time('process');
// do stuff
console.timeEnd('process'); // log time passed since console.time

Basic Timer Polyfill

var Timer = function(name) {
  var start = new Date();
  return {
    stop: function() {
      var end  = new Date();
      var time = end.getTime() - start.getTime();
      console.log('Timer:', name, 'finished in', time, 'ms');
    }
  }
};

var t = new Timer('Description');
// do stuff
t.stop();

Last modified: 202107020540

Operators (Javascript)

Logical Operators

In Javascript, all of these operators on truthy and falsy values, meaning that all values will be converted to boolean before comparison.

Used with Non-Boolean Types

When using non-boolean values, the return value will not be a boolean, but one of the values compared.

AND (&&)

If all are truthy, it will return the last compared value. However, if any of the values are falsy, if will return the first falsy value.

const a = 1 && 2 && 3; // returns 3
const b = 4 && 0 && 'yes' && false // returns 0

AND Assignment (&&=)

If x is truthy, define x with what follows. This is fairly new, so only use this if you know if will be safe to use in production.

let x = 4;
let y = false;
x &&= 10; // x === 10
y &&= true; // y === false

OR (||)

OR will return the first truthy value found. If all are falsy, will return the last value.

const a = 1 || 2 || 3; // returns 1
const b = null || 0 || false; // returns false

OR Assignment (||=)

If x is falsy, define x with what follows. This is fairly new, so only use this if you know if will be safe to use in production.

let x = 4;
let y = false;
x ||= 10; // x === 4
y ||= true; // y === true

NOT (!)

Using a double NOT will convert a regular value into a boolean.

const a = !!'hello'; // returns true
const b = !!0; // returns false
const c = !!undefined; // returns false

Nullish Operator (??)

Will return the right hand side operand if the left side is null or undefined.

const a = 0 ?? 2; // returns 0
const b = null ?? 2; // returns 2

Nullish Assignment (??=)

If x is nullish (null or undefined), define x with what follows. This is fairly new, so only use this if you know if will be safe to use in production.

let x = 4;
let y = undefined;
x ??= 10; // x === 4
y ??= true; // y === true

References

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators

Last modified: 202106291353

Classes (Javascript)

Classes in Javascript generally are created with two different sections:

  1. The prototypes or methods will be how all the instances of the class should be similar (things like addYear for a person class). This is commonly done in the prototype object.
  2. The constructor will define how the instances are different (the name property of a person class). This is commonly done through the invocation of the constructor, like function (name) { this.name = name }.

Class Types

Decorators

A decorator is a function that accepts an object and adds more properties or functionality to it. It's common to use adjectives as the names of these decorators. Decorators allow for more DRY code and help keep all elements together that should be, allowing little ambiguity in execution.

// this decorator makes obj more 'carlike'
var carlike = function (obj, loc) {
  obj.loc = loc;
  obj.move = function () {
    obj.loc++;
  };
};

var newObj = {};
var newCar = carlike(newObj, 0);

Functional Classes

A functional class is a construct that is capable of making a fleet of objects that conform to the same interface. They are commonly capitalized in name. The functions that produce these functional classes are called constructors. The object that is returned is called an instance of that class.

The difference between a decorator and a functional class is that a decorator accepts their target object as input, whereas the class builds and returns the object it's augmenting.

var Car = function (loc) {
  var obj = {loc: loc};
  obj.move = function () {
    obj.loc++;
  }
  return obj;
}

var newCar = Car(0);

Functional Classes with Shared Methods

Using shared methods allows you to save space in memory, as only one instance of a method needs to exist, as opposed to one for every single instance.

var Car = function (loc) {
  var obj = {loc: loc};
  // using UnderscoreJS (see polyfill)
  return _.extend(obj, carMethods);
}

var carMethods = {
  move: function () {
    this.loc++;
  }
}

var newCar = Car(0);

_.extend polyfill:

var extend = function (destination, source) {
  for (var key in source) {
    destination[key] = source[key];
  }
  return destination;
}

Prototypal Classes

Using Object.create(), we can create an object that inherits all properties of the enclosed object into its prototype. This will mean that on a failed lookup, it will search within this object for a reference, inheriting the old objects as they were at the time of inheritance.

var Car = function (loc) {
  var obj = Object.create(Car.prototype);
  obj.loc = loc;
  return obj;
}

Car.prototype.move = function () {
  this.loc++;
};

var newCar = Car(0);

Pseudoclassical Classes

The pseudoclassical class is a Javascript syntactic sugar that allows a more conventional style of object oriented programming to be implemented.

By running a function with the new keyword before it, the interpreter runs the program in a special "construction" mode. Since you will always want to be creating an object and returning it when you are finished, the new keyword adds these two lines at the beginning and end, respectively, to your function. The object created will be automatically bound to this and will use the prototype property found inside that function.

The two different parts of a pseudoclassical class are doing two distinct roles:

  1. the constructor is defining what is different about each instance. In this example, what loc is.
  2. the methods are defining what is similar about each instance. In this example, what move does.
var Car = function (loc) {
  this.loc = loc;
};

Car.prototype.move = function () {
  this.loc++;
};

var newCar = new Car(0);

ES6 Classes (class)

The ES6 implementation is extremely similar to the pseudoclassical implementation, but uses more syntactic sugar to make it more readable and more similar to other object-oriented languages.

class Car {
  constructor(loc) {
    this.loc = loc;
  }

  move() {
    this.loc++;
  }
}

var newCar = new Car(0);

Polymorphism

Polymorphism is the design of objects to be able to share behaviors and override certain shared behaviors to work more specifically on the new object. There is a super class and a sub class. The sub class inherits the properties and methods from the super class. In the following examples, the super is Shape and the sub is Square or Triangle.

Functional Classes

var Shape = function (name, sides, sideLength) {
  var obj = {
    name: name,
    sides: sides,
    sideLength: sideLength
  };
  var calcPerimeter = function () {
    return obj.sides * obj.sideLength;
  };
  return obj;
};

var Square = function (name, sideLength) {
  var obj = shape(name, 4, sideLength);
  var calcArea = function () {
    return Math.pow(obj.sideLength, 2);
  };
  return obj;
}

var newSquare = Square('square', 5);

Functional with Shared Methods

Using _.extend to update the object.

var Shape = function (name, sides, sideLength) {
  var obj = {
    name: name,
    sides: sides,
    sideLength: sideLength
  };
  // using UnderscoreJS (see polyfill)
  return _.extend(obj, shapeMethods);
};

var shapeMethods = {
  calcPerimeter: function () {
    return this.sides * this.sideLength;
  }
};

var Square = function (name, sideLength) {
  var obj = Shape(name, 4, sideLength);
  return _.extend(obj, squareMethods);
}

var squareMethods = {
  calcArea: function () {
    return Math.pow(this.sideLength, 2);
  }
};

var newSquare = Square('square', 5);

Prototypal Classes

Using Object.create().

var Shape = function (name, sides, sideLength) {
  var obj = Object.create(Shape.prototype);
  obj.name = name;
  obj.sides = sides;
  obj.sideLength = sideLength;
  return obj;
};

Shape.prototype.calcPerimeter = function () {
  return this.sides * this.sideLength;
};

var Square = function (name, sideLength) {
  var obj = Object.create(Square.prototype);
  obj.name = name;
  obj.sides = 4;
  obj.sideLength = sideLength;
  return obj;
}

Square.prototype = Object.create(Shape.prototype);
Square.prototype.constructor = Square; // otherwise is `Shape`
Square.prototype.calcArea = function () {
  return Math.pow(this.sideLength, 2);
};

var newSquare = Square('square', 5);

Pseudoclassical Classes

Using the new keyword.

var Shape = function (name, sides, sideLength) {
  // this = Object.create(Shape.prototype);
  this.name = name;
  this.sides = sides;
  this.sideLength = sideLength;
  // return this;
};

Shape.prototype.calcPerimeter = function () {
  return this.sides * this.sideLength;
};

var Square = function (name, sideLength) {
  this.name = name;
  this.sides = 4;
  this.sideLength = sideLength;
};

Square.prototype = new Shape();
Square.prototype.constructor = Square; // otherwise is `Shape`
Square.prototype.calcArea = function () {
  return Math.pow(this.sideLength, 2);
};

var newSquare = new Square('square', 5);

ES6 Classes

To create a class that inherits all the properties of another class, use extends after defining the class name.

class Shape {
  constructor (name, sides, sideLength) {
    this.name = name;
    this.sides = sides;
    this.sideLength = sideLength;
  }

  calcPerimeter () {
    return this.sides * this.sideLength;
  }
};

class Square extends Shape {
  constructor (name, sideLength) {
    super(name, 4, sideLength);
  }

  calcArea () {
    return Math.pow(this.sideLength, 2);
  }
}

var newSquare = new Square('square', 5);

Property Lookup/Prototype Chains

If you are looking for a given property of an object, the interpreter will first look at the object itself, and if it fails on that lookup, will look at any other objects that are associated via prototype chain.

To have an ongoing prototype chain, where one object will always default on a failed lookup to searching within another object, you can use var newObj = Object.create(oldObj). newObj will now default to looking up any failed lookups in oldObj. The values will be calculated during the lookup time, as the values are not stored or copied into the new object. The new object has a link to the old object and will perform on a lookup on the old object in its current state.

References

  1. http://underscorejs.org/#extend
  2. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
  3. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
  4. https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript
  5. https://stackoverflow.com/questions/44391149/es6-classes-ability-to-perform-polymorphism
  6. https://radialglo.github.io/blog/2014/11/24/understanding-pseudoclassical-inheritance-in-javascript/

Last modified: 202107020555

How To Load Local JSON Files

Put the local JSON file in a Javascript file and prepend the JSON with const variableName = and just treat it like an object literal. Put the file you created before your main app file in the HTML and you will be able to access it.

Last modified: 202107020540

server

There's currently nothing here.

Backlinks:

Last modified:

Higher Order Functions

A higher-order function either takes in a function as an argument, or returns a function.

Callback Functions

When taking a function as a parameter, this is called a callback function. This is used in Javascript built-ins like setTimeout, filter, map, and forEach.

var arr = [1,2,3,4];
var add2 = function (num) {
  return num + 2;
};
var newArr = arr.map(add2); // result: [3,4,5,6]

Closures

Functions that return other functions can create closures, which means that the variables within which the function is defined will remain accessable by that function; the variables are enclosed within that function's own scope.

In the example below, a function called counter keeps track of how many times it is called. Even though the function runs and fully completes, the reference to this execution context remains with the function that is returned at the conclusion of that invocation. We cannot directly access count from outside of the scope of counter, but with the returned function, we can add to it and see what count's value' is at that point.

var counter = function () {
  var count = 0;
  console.log(count);
  var add1 = function () {
    count++;
    console.log(count);
  };
  return add1;
};

// newCounter will now reference the `add1` function within the closure of that invocation of counter
var newCounter = counter(); // 0
// This calls `add1` within that same closure, incrementing `count` by 1
newCounter(); // 1

References

  1. https://en.wikipedia.org/wiki/Higher-order_function

Backlinks:

Last modified: 202106291359

Apply, Call and Bind in Javascript

Apply, bind, and call are higher order functions that help with this.They allow you to invoke a function, which would normally be called from and on the same object, and change which object to which it will be applied.

Apply and Call

// functionName.apply(newThis, [arguments, moreArguments]);
// functionName.call(newThis, arguments, moreArguments);

const numbers = [5, 6, 2, 3, 7];
const max = Math.max.apply(null, numbers);
console.log(max); // expected output: 7

const min = Math.min.apply(null, numbers);
console.log(min); // expected output: 2

While the syntax of apply and call are almost identical, the fundamental difference is that apply accepts an array of arguments, and call accepts a comma-separated argument list.

Bind

The bind() method returns a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

var num = 2;
var x = { num: 6 };

var addTwo = function () {
  return this.num + 2;
};

var addTwoToX = addTwo.bind(x);

addTwo();    // returns 4 since this.num = 2
addTwoToX(); // returns 8 since this.num = 6

References:

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
  2. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

Backlinks:

Last modified: 202106291328

Switch Case (Javascript)

Switch cases in Javascript act very similar to if/else statements with one very important caveat, being that they will trip the condition that matches and all that follow it unless a specific break is made. Default is a special case that will only trip if no other conditions are met or if break is not invoked.

const number = 1;

switch (number) {
  case -1:
    console.log('Definitely negative 1');
    break;
  case 1:
    console.log('True');
    break;
  case 0:
    console.log('False');
    // Will fall through to default as no explicit `break` was made
  default:
    console.log('Definitely not -1');
}

// Logs 'True'
// number = 2: 'Definitely not -1'
// number = 0: 'False', 'Definitely not -1'

References

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch

Last modified: 202106291341

DOM Manipulation (Javascript)

How to manipulate the HTML DOM using Javascript.

Elements

  • X = document.createTextNode('text')
  • X = document.createElement('li')

Alteration

<!-- beforebegin -->
<p>
  <!-- afterbegin -->
  foo
  <!-- beforeend -->
</p>
<!-- afterend -->
  • X.textContent = 'text'
  • X.innerText = 'text'
  • X.childNodes[n].nodeValue = '...' will allow you to change the inner text of an element, even when it includes another element (e.g. changing some more text in <span><em>yeah</em>some more text</span>)

Insertion

  • X.appendChild(Y) will append element Y as the last child of element X

  • X.prepend(Y) will prepend element Y as the first child of element X

  • X.parentNode.insertBefore(Y, X); will insert element Y directly before element X

  • X.parentNode.insertBefore(Y, X.nextSibling); will insert element Y directly after element X

Duplication

  • X.cloneNode(true) will return a copy of the selected element.

Search

  • X.querySelector(Y) will find the first element based on CSS element search Y within the tree of elements found at X.
  • X.querySelector(Y) will find all elements based on CSS element search Y within the tree of elements found at X.
  • X.closest(Y) will find an element based on CSS element search Y from element X up through all of the parents to the top of the DOM

DOMParser

The DOMParser allows you to parse HTML in as a string, returning an HTMLDocument object. This allows you to interact with the DOM elements and alter them much more simply and easily than using regex or find/replace in a text-editor.

The DOMParser operates very similarly to jQuery's ability to parse HTML in as a string within $('<input>'). The difference is that DOMParser returns an HTMLDocument instead of a jQuery object.

Importing Plain Text

const parser = new DOMParser();
const htmlDoc = parser.parseFromString(input, 'text/html');

Exporting Plain Text

You can return each of the top level elements (head, body) as plain text using innerHTML.

return htmlDoc.body.innerHTML;

References

  1. https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
  2. https://api.jquery.com/jQuery/
  3. https://www.udemy.com/course/modern-javascript-from-the-beginning/learn/lecture/8757274
  4. https://gomakethings.com/how-to-copy-or-clone-an-element-with-vanilla-js/
  5. https://stackoverflow.com/questions/4106809/how-can-i-change-an-elements-text-without-changing-its-child-elements
  6. https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML

Last modified: 202107041952

Lexical Scoping (Javascript)

Lexical Scoping defines how variable names are resolved in nested functions: inner functions contain the scope of parent functions even if the parent function has returned.

With Javascript, a new scope is created only through function definitions. Every time a new function scope is created, it will contain the scope of the parent functions, along with its own. This does not go both ways, however: the outer scope does not have access to those in the inner scope.

var content = "I'm outside";
var outermost = " and I'm still here."

var middle = function () {
  var content = "I'm in the middle";
  var inner = function () {
    var content = "I'm inside"; 
    console.log(content + outermost); // "I'm inside and I'm still here."
  };
  inner();
  console.log(content + outermost);   // "I'm in the middle and I'm still here."
};

middle();
console.log(content + outermost);     // "I'm outside and I'm still here."

this

this, within a function, is bound to the object within which the function is being called. Look to the left of the calltime dot to find the binding of this. The Javascript interpreter binds this to a likely-focal object, which means it isn't always what you think it is. Assume its binding will run into trouble, so you may need to at times manually set this to the desired object.

  • If you have defined your function in the global scope, then this is implicitly bound to the global context, which in a browser is window. You can call this function funcName also by calling window.funcName
  • If you have defined your function as part of an object, like var obj = { funcName: function (a) { ... } }, then this is bound to obj.
var obj = {
  greeting: function () { console.log(this.message ) },
  message: "Hello world"
}
obj.greeting(); // `this` is bound to `obj`; logs "Hello world"
var g = obj.greeting;
g() // `this` is bound to the *global object*
    // logs "undefined" because there is no variable "message" in the global scope

References:

  1. https://stackoverflow.com/questions/1047454/what-is-lexical-scope
  2. http://howtonode.org/what-is-this
  3. https://medium.com/better-programming/how-javascript-works-1706b9b66c4d

Last modified: 202107080233

Variables (Javascript)

All variables in Javascript are undefined by default after declaration.

Difference Between Var, Let, and Const

Use const over let and let over var unless:

  • The value may change
  • The var needs to be initialized
  • It is used in an iterator or a loop

Block scoped means within a block or indentation level (starting with { and ending with }) or outside of a function. This means that one can use let outside of a function and declare a new variable with let again within a function.

const

const is block scoped. Short for "constant", meaning that it is a variable that once defined, cannot be redefined, changed through reassignment, redeclared, or updated. This also means one can cannot initialize a variable through const without a value. const can only be accessed within the scope they were created.

const greeting = "Hello there!";
// This can never be changed, as it is a constant.
greeting = "Hi."; // This throws an error

Reference types created with const can have their attributes updated, but cannot be updated itself.

const greeting = {
    "brothers" = 3;
}

// Not accepted, since `greeting` is has already been declared and assigned a value
const greeting = {
    "sisters" = 2;
}

const brothers = 1; // Accepted
const brothers; // Unaccepted

let

let is also block scoped; let variables can be updated, but not redeclared.

let greeting = "Hello there!";
greeting = "Hi.";
// This throws an error and won't work
let greeting = "Hey hey hey";

var

var variables are function scoped and not a constant. Even when defined within a function, they can affect the global scope. These variables can also be redeclared and updated at any point.

As of ES2015, const and let are fully supported in modern browsers, so var is not advised.

var greeting = "Hello there!";
var greeting = "Hey bayBEE!";
//These are all acceptable

Define Multiple Variables At Once

One can use commas to const many different variables at once.

const yes = 'yes',
      no = 'no',
      hi = 'hi';

Global Declaration

Global variable declarations are made by using no keyword before the definition:

greeting = "Hi.";

Assignment as an Expression (a la Walrus Operator)

You can define a variable while running a condition on an if or a while loop. This can help remove extra lines of code or going through variables over and over. Since the innermost parentheses get resolved first, it will function normally after assignment.

let i = 0;
while (i !== 3) {
  console.log(i);
  i++;
}

// Logs (0, 1, 2)

// Written using assignment as an expression

let i = -1;
while ((i = i + 1) < 3) { // === (i = i + 1) < 3 === i < 3
  console.log(i);
}

// Logs (0, 1, 2)

Hoisting

The JS code interpretation performed in two passes. During the first pass, the interpreter processes variable and function declarations. The second pass is the actual code execution step. The interpreter processes function expressions and undeclared variables.[7]

Hoisting Variables

The term "hoisting" is meant to represent a literal hoisting of variable and function declarations to the top of a Javascript file, where they will be declared before the file is interpreted (while this is not technically what happens, it's certainly more memorable).

Consider the following example:

var a = 1;
console.log(a + ' ' + d);
var d = 3;

In this example, because interpreters normally run from top to bottom, executing each line as they go, one would expect an error thrown at the console.log because it would not be aware of any variable named d. Because of hoisting, however, d is declared by the interpreter but not initialized with a value, so it actually logs undefined instead.

Another weird case:

var a = 1;
d = 3;
console.log(a + ' ' + d);
var d;

Since the declaration of d (var d;) is "hoisted" above the assignment (d = 3;), this actually does not throw any errors and logs 3.

Hoisting Functions

The hoisting of functions is similar to variable hoisting, in that the declaration of any named functions will be "hoisted". However, what makes functions different in this is that their definition will be hoisted as well as their declaration.

In general, you do not want to hoist any functions within the browser unless you have a good reason, since it costs a lot of extra memory for the browser. This can be avoided by using anonymous functions as opposed to named functions like below:

// Outputs: "Definition hoisted!"
definitionHoisted();

// TypeError: undefined is not a function
definitionNotHoisted();

// named function
function definitionHoisted() {
    console.log("Definition hoisted!");
}

// anonymous function
var definitionNotHoisted = function () {
    console.log("Definition not hoisted!");
};

References:

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
  2. https://www.udemy.com/course/modern-javascript-from-the-beginning/learn/lecture/8757146#overview
  3. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
  4. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
  5. http://www.ecma-international.org/ecma-262/6.0/index.html
  6. https://www.youtube.com/watch?v=ppMlvGMT2qE
  7. https://stackoverflow.com/questions/15005098/why-does-javascript-hoist-variables
  8. http://adripofjavascript.com/blog/drips/variable-and-function-hoisting.html

Last modified: 202106291355

Event Listeners (Javascript)

Event listeners in Javascript run a function on the emitting of an event, including click, keyup, resize, and more.

element.addEventListener('eventType', function(e) {
  // do something
});

This adds a listener to whatever element it is attached to. It waits for the 'event' to occur, and once it does, it calls the callback function. The e (short for event)is the callback object, which can give you information on the event and its related elements.

One can also pass in a named function instead of use an anonymous one. This can lead to cleaner code, as it is more declarative than imperative

element.addEventListener('event', onClick);

function onClick(e){
  // do something
};

There is a third Boolean parameter of addEventListener that specifies if you want the handler to fire on capture or bubble. It defaults to false, which is bubble. But if you set it to true, it will fire on capture.

The Event Object

The e that is in the functions pertaining to eventListener's in Javascript is the object that is returned by a specific event with many parameters like the coordinates of the click, the element clicked, etc. If you have an eventListener attached to a certain element that will trigger on a click, then when the user clicks, it will return an event object. This event object is what gets passed as e into the function.

e.target is used to specify the element on which you clicked.

Event Bubbling and Delegation

Event bubbling is where an event listener attached to a certain element will be triggered by a child element. This is because of the elements being nested within each other. If div2 is nested within div1, a trigger on div2, will also trigger div1, since div2 is nested within div1.

Event delegation is a pattern where an event listener attached to an element is not triggered unless a specified child element is the trigger. This is useful if there are many elements that have the same class name or ID and you want an action done to a specific one. It is done through if statements on the callback specifying attributes like class name or id.

<div id="outer">
  <div id="inner-1">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
  </div>
  <div id="inner-2">No</div>
</div>
// This will fire on any click that happens on it or any of its child elements (bubbling to the top component)
document.getElementById('outer').addEvenetListener('click', () => console.log('bubbled'));

// This will fire only when a specific child or any of its children are clicked (delegated to specific children)
document.getElementById('outer').addEvenetListener('click', () => {
  const innerOne = event.target.closest('#inner-1');
  if (innerOne) {
    console.log('delegated');
  }
});

Most Common Event Types

  • blur - The event occurs when an element loses focus
  • change - The event occurs when the content of a form element, the selection, or the checked state have changed (for <input>, <select>, and <textarea>)
  • click
  • DOMContentLoaded - The event occurs when the HTML has been fully parsed and loaded.
  • focus
  • keydown/keyup
  • keypress
  • mousedown/mouseup
  • mouseenter/mouseleave/mousemove/mouseover/mouseout/mouseup
  • submit - The event occurs when a form is submitted

References:

  1. https://www.udemy.com/course/modern-javascript-from-the-beginning/learn/lecture/8757278#content
  2. https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
  3. https://stackoverflow.com/questions/35936365/what-exactly-is-the-parameter-e-event-and-why-pass-it-to-javascript-functions
  4. https://www.udemy.com/course/modern-javascript-from-the-beginning/learn/lecture/8762202#content
  5. https://www.udemy.com/course/modern-javascript-from-the-beginning/learn/lecture/8757286#content
  6. https://www.w3schools.com/jsref/dom_obj_event.asp

Last modified: 202107032208

Mocha and Chai (Javascript)

Mocha is a Javascript test framework for use with Node, and Chai is an assertion library.

Another common library to use with Mocha is nyc, which allows you to get a code coverage readout. You can use this by npm i nyc and then adding it to your package.json as a script: "coverage": "nyc npm run test".

Quick Start

Install Mocha and Chai using npm i --save-dev mocha chai.

In your package.json, replace the value of the "test" property within "scripts" with "mocha ./path/to/tests", inserting the path to your tests.

Create a file called example.js within your test folder. Place this inside:

const assert = require('chai').assert;

describe('Sum', () => {
  it('should add 2 and 2 to equal 4', () => {
    assert.equal(2 + 2, 4);
  });
});

Save this file and in your terminal, run npm run test. This should render a screen showing a test, "should add 2 and 2 to equal 4", passing within the "Sum" section.

Assert

All are assumed to start with assert.

Comparison

Invoked with (actual, expected).

Chain Effect
.equal, .notEqual Non-strict equality (==)
.deepEqual, .notDeepEqual Strict equality (===), also used for objects

Simple

All are accompanied with a negative assertion, e.g. .isX/ .isNotX.

  • .exists(x)
  • .include([x,y,z], x)
  • .deepInclude([obj1, obj2], obj1)
  • Every primitive (.isNumber, .isBoolean, isTrue, etc.)

Asynchronous Tests

References

  1. https://mochajs.org/
  2. https://www.chaijs.com/
  3. https://www.chaijs.com/api/assert/
  4. https://gist.github.com/yoavniran/1e3b0162e1545055429e#jest
  5. https://www.testim.io/blog/testing-promises-using-mocha/

Last modified: 202107230513

Typescript

Typescript is a superset of Javascript that is strongly typed and values specificity.

Casting

You can cast one type as another in a couple different ways.

// In these examples, query selector will naturally return an HTMLElement. To 
// access the `value`, we will need to cast it as an HTMLInputElement.

let input;

// using 'as'
input = document.querySelector('input[type="text"]') as HTMLInputElement;

// using <>
input = <HTMLInputElement>document.querySelector('input[type="text"]');

When using TypeScript with JSX, only as-style assertions are allowed.

Type Annotations

Type annotations are done at the declaration of a variable with a colon followed by the type or interface.

// Primitives
const greeting: string = "Hello there!";

// Arrays
const numbers: number[] = [1, 2, 3, 4];

// Generics
const uniqueCharacters: Set<string> = new Set(['a', 'b', 'c']);

// Interfaces/Types
interface Person {
  name: string,
  age: number,
  sayHi: () => string,
}
const johnSmith: Person = {
  name: "John Smith",
  age: 40,
  sayHi: () => return greeting;
};

// Functions
const add = (a: number, b: number): number => {
  return a + b;
};

Annotations with Object Destructuring

// without annotation
const getNameAndAge = ({ person, job }) => {
  const {
    name,
    age,
  } = person;
  return `${name}: ${age}, ${job}`;
};

// with annotation
const getNameAndAge = 
      ({ person, job }: { person: { name: string, age: number }, job: string }) => {
  const {
    name: string,
    age: number,
  } = person;
  return `${name}: ${age}, ${job}`;
};

// with type or interface
type Person = {
  name: string,
  age: number
};

const getNameAndAge = ({ person: Person, job: string }) => {
  const {
    name: string,
    age: number,
  } = person;
  return `${name}: ${age}, ${job}`;
};

Unique Typing Troubleshooting

Property '***' does not exist on type 'never'

This means that the target variable has not ben typed correctly and often will show up when something has not been given a type at all.

// incorrect
const thing = 'Oh yeah!';
const things = [1,2,3,4];
const specificThing = { name: 'John', age: 9 };
// correct
const thing: string = 'Oh yeah!';
const things: number[] = [1,2,3,4];
const specificThing: InterfaceName = { name: 'John', age: 9 };

useState

With useState in React hooks, you will need to use a special syntax in creation of the hooks themselves. Since useState is a generic function, the typing happens within the <> characters.

const [editedHashtagListeners, setEditedHashtagListeners] = useState<HashtagListener[]>([]);

Interface and Type

Interfaces and types are two ways to define a type of object, declaring the types of the contained properties.

Differences

Type

type Person = {
  name: string,
  age: number,
  pets: string[]
};

const john: Person = {
  name: 'John',
  age: 40,
  pets: ['Mary', 'Doug']
};

const household: Person[] = [john];

Interface

interface Person {
  name: string,
  age: number,
  pets: string[]
};

const john: Person = {
  name: 'John',
  age: 40,
  pets: ['Mary', 'Doug']
};

const household: Person[] = [john];

Creating Fixed Values

type Roles = 'owner' | 'admin';

interface User {
  name: string;
  // value must be an array containing values within Roles
  roles: Roles[];
}

Defining Unknown Property Keys

type Roles = 'owner' | 'admin';

interface Channel {
  id: string;
  name: string;
}

interface User {
  name: string;
  channels: {
    // channel at `index` must be a string
    // value must be an array containing values within Roles
    [index: string]: Roles[];
  }  
}

References:

  1. https://stackoverflow.com/questions/52423842/what-is-not-assignable-to-parameter-of-type-never-error-in-typescript
  2. https://stackoverflow.com/questions/53598449/react-hooks-and-typescript-property-does-not-exist-on-type-never
  3. https://stackoverflow.com/questions/41443242/how-to-correct-flow-warning-destructuring-missing-annotation
  4. https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#differences-between-type-aliases-and-interfaces
  5. https://lzomedia.com/blog/how-to-apply-type-annotations-to-functions-in-typescript/
  6. https://stackoverflow.com/questions/12989741/the-property-value-does-not-exist-on-value-of-type-htmlelement
  7. https://stackoverflow.com/questions/61851004/describe-interface-fixed-values-in-array-element-of-typescript
  8. https://stackoverflow.com/questions/23914271/typescript-interface-definition-with-an-unknown-property-key

Backlinks:

Last modified: 202107301940

ESLint

Enforce rules and raise warnings to keep your Javascript, Typescript, and React code clean and bug free.

Ignore rule in a file

By placing this at the top of the file, it will ignore this rule throughout the entire file. /* eslint-disable {rule} */

To disable a rule for only one line, place this after the code on the offending line. // eslint-disable-line {rule}

Last modified: 202107291557

HTTP

There's currently nothing here.

Backlinks:

Last modified:

AJAX

AJAX stands for Asynchronous Javascript And XML. It is an asynchronous way to get and send data. Usually used with JSON. AJAX is built in to Javascript.

When an AJAX call is made in your Javascript code, the AJAX engine takes your request and converts it into a proper XmlHttpRequest. The website that is being queried then responds (with JSON or XML) and the AJAX engine then converts it into an HTML response that can be parsed by Javascript.

Ajax is able to asynchronously handle HTTP requests and responses, interpreting the requests from JS to HTTP and responses from JSON to HTML responses. This allows a fluid application that doesn't need to refresh the browser to function.

A standard implementation of AJAX involves these steps:

  1. Creating the XHR object
  2. Defining the request parameters
  3. Instructions on a successful and unsuccessful request
  4. Sending/starting the request

XMLHttpRequest (XHR Object)

XMLHttpRequest is an API that is in the form of an object, with methods and properties attached. When a request is made and when a response is received, all of that work goes on behind the scenes and this object is updated as things happen.

To use the XHR object, a new instance needs to be created and assigned to a variable.

var xhr = new XMLHttpRequest();

.open()

.open() is an XHR function that takes three parameters: type of request, URL or file name, and a boolean of whether it is asynchronous or not.

xhr.open('GET', 'https://www.requestURL.com', true);

.onreadystatechange

You define a function at that property, and it will run every time the readyState property of the XHR object changes. The readyState values are:

  • 0 - Request not initialized
  • 1 - server connection established
  • 2 - request received
  • 3 - processing request
  • 4 - request finished and response is ready
xhr.onreadystatechange = function () {
  // if the readyState property of the XHR object ('xhr') is 4
  // AND the status in the XHR object is 'OK'
  if (this.readystatechange == 4 && this.status === 200) {
    // get the responseText from the XHR object ('xhr')
    console.log(this.responseText)
  }
}

.onprogress

.onprogress is a property that holds a function, defined by the developer, that will be called once the readyState is at 3, when the request is being processed.

xhr.onprogres = function () {
  // Show the loading image or something that denotes waiting  
}

.onload / .onerror

.onload and .onerror are properties that hold functions, defined by the developer, that will be called once the readyState is at 4, when the request is finished and response is ready, or when an error is detected.

xhr.onload = function () {
  // if the status in the XHR object (xhr) is 'OK'
  if (this.status === 200) {
    // get the responseText from the XHR object ('xhr')
    console.log(this.responseText)
  }
};

xhr.onerror = function () {
  console.log('Request error');
};

.setRequestHeader()

When making a POST request, you will need to set the request header. This function takes two parameters: the name of the header and the value it will have. This can be called multiple times in a row to set multiple parameters, and they will all be compiled together to one header. Learn more about HTTP headers here.

xhr.setRequestHeader('Content-type', 'application/json');

.send()

This will send the request that has already been created by .open(). The body of the request should be passed in as a parameter, but it is optional, like in a simple GET request.

xhr.send();

Response Data Types

All of the previous examples have been for if you are making a request for a plaintext file, by getting the responseText property from the XHR object. If your response ends up being a JSON file, you can parse this with JSON.parse(this.responseText).

Libraries


References

  1. https://www.youtube.com/watch?v=82hnvUYY6QA
  2. https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

Last modified: 202107020539

Regular Expressions (Javascript)

In Javascript, regular expressions are enclosed within two forward slashes and flags are placed oustide.

let re = /hello/m;  // or
let re = new RegExp('hello', 'm');

Methods

.exec() / .match()

re.exec(item) and item.match(re) will search for the regex (re) inside of item. If found, this returns the expression, the index of beginning of match, and the input item. if not found, this returns null.

.replace()

item.replace(re, replacement) will replace instances of regex (re) with replacement and return the modified item.

.search()

item.search(re) returns index of first found instance of reg ex in item. if not found, returns -1.

.source()

re.source returns the reg expression without the slashes, re being a variable holding a regular expression.

let re = /hello/m;
console.log(re.source); // "hello"

.split()

item.split(re) returns an array of the string split by the regex.

var myString = 'Hello 1 word. Sentence number 2.';
var splits = myString.split(/(\d)/);
// returns [ "Hello ", "1", " word. Sentence number ", "2", "." ]

.test()

re.test(item) returns boolean of if regex is found in item.

let re = /hello/m;
re.test('hello world!') // returns true
re.test('me first') // returns false

References

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split

Last modified: 202107020550

React Hooks

Hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks allow the simplicity of functional components with the complexity and flexibility of class components.

Types

These examples are using Typescript for type annotations and clarity.

useState

useState lets you use state within a functional component.

import React, { useState } from 'react';

interface Name {
  first: string,
  last: string,
}

const testComponent = () => {  
  // this will create a getter and setter for state variable `names`
  const [counter, setCounter] = useState<number>(0);
  const [names, setNames] = useState<Name[]>([]);

  // sets counter 
  setCounter(counter + 1);

  const newName = {
    first: 'John',
    last: 'Smith',
  };
  setNames([
    ...names,
    newName
  ]);

  ...

useEffect

useEffect lets you perform side effects on useState changes, effectively replacing componentDidMount and componentDidUpdate.

import React, { useEffect } from 'react';

const testComponent = () => {
  ...

  // this will run on every rerender (generally don't want this)
  useEffect(() => {
    // do stuff
  });

  // this will run the function once on mount
  useEffect(() => {
    // do stuff
  }, []);

  // this will run anytime that variable `names` is changed
  useEffect(() => {
    // do stuff
  }, [names]);

  ...

References

Last modified: 202107301716

React from Scratch

Learn how React works by building it without the create-react-app framework.

For React to work properly, you will need three things:

  • Babel - This is a transpiler that will allow you to use JSX within your components and make your site usable to clients that do not have ES6 functionality available.
  • Webpack - This is a compiler that will take all of your modules, styles, etc. and put them together.
  • React - This is the meat and potatoes that will render your page, let you use state, hooks, etc.

The easiest way to do this is with create-react-app. But if you want to know how it works:

Get all your parts

  • Initialize a new npm project with npm init. You can skip all the questions with the -y flag.

  • Install babel in your development dependencies: npm install --save-dev @babel/core @babel/preset-env @babel/preset-react.

    • @babel/core — This contains the babel core configuration,
    • @babel/preset-env — This contains different plugins, the most important of which transforms all ES2015-ES2020 code to be ES5 compatible (the one JavaScript version where almost all browsers implement)
    • @babel/preset-react — This contains different plugins to enable React syntax parsing and transformation.
  • Install babel-loader for webpack to use: npm install --save-dev babel-loader

    • To transform our code, we will use a package called babel-loader. babel-loader will allow us to transpile our JavaScript file using babel and webpack.
  • Install webpack in your development dependencies: npm install --save-dev webpack webpack-cli webpack-dev-server

    • webpack — the core webpack functionality package.
    • webpack-cli — this package is necessary to use the CLI.
    • webpack-dev-server — this is for the dev server that allows live reloading
  • Install react in your project. npm install react react-dom

  • Create the public-facing folder for the client, and an app.js within a sibling src folder

Make your webpack config and babel config

In the root folder, create a webpack.config.js file that pulls in the node path module. This is where you will be putting your entry and output points in your webpack builders. (TA: Search 'webpack configuration' and you should be reminded of all the things you need.)

const path = require('path');

module.exports = {
  entry: '.src/app.js',     // which file your app will be pulling the data from for it's dependency graph
  output: {
    filename: 'bundle.js',  // the name of the file it will output the bundle to
    path: path.join(__dirname, 'public'),  // the output folder fo your bundles
  },
  module: {  // determines which loader to use
    rules: [{
      loader: 'babel-loader',
      test: /\.jsx?$/,            // transform js files
      exclude: /node_modules/,  // but not node_modules
    }]
  },
  devServer: {
    contentBase: path.join(__dirname, 'public'), // where to serve from when running the webpack dev server
  }
}

In the root folder, create a file called babel.config.json. (TA: Search for 'babel config' and you should be able to find everything you need.)

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}

babel-loader will try to find the babel configuration file —this babel.config.json. The code in this file instructs babel-loader to use @babel/preset-env and @babel/preset-react presets that we have installed earlier when transpiling our code.

Add scripts in package.json for running webpack

"scripts": {
  "build": "webpack",
  "start": "webpack serve", 
  "watch": "webpack --watch"
}

Create your documents

In public, make the html page you will inject into. This needs to have the injection point as well as the webpack bundle.

<!doctype html>
<html>
  <head>
    <title>Test</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="bundle.js"></script>
  </body>
</html>

In src, create the React JS page that will inject your app into the root div.

import React from 'react';
import ReactDOM from 'react-dom';

const App = () => {
  return (
    <div>
      <h1>Wow! This is some stuff.</h1>
    </div>
  )
}

ReactDOM.render(
  <App />, 
  document.getElementById('root')
);

Test it out by running npm run start and checking it in a browser.

References

  1. https://medium.com/swlh/back-to-basics-how-to-set-up-a-react-app-from-scratch-2020-134908e17490

Backlinks:

Last modified: 202107081809

React Router

React Router is a way to link to other pages dynamically within your React single page application.

All of these examples were pulled straight from the docs.

Installation

npm install react-router-dom

Usage

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";

export default function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/users">Users</Link>
            </li>
          </ul>
        </nav>

        {/* A <Switch> looks through its children <Route>s and
            renders the first one that matches the current URL. */}
        <Switch>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/users">
            <Users />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

function Home() {
  return <h2>Home</h2>;
}

function About() {
  return <h2>About</h2>;
}

function Users() {
  return <h2>Users</h2>;
}

Nested Routing

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  useRouteMatch,
  useParams
} from "react-router-dom";

export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
          <li>
            <Link to="/topics">Topics</Link>
          </li>
        </ul>

        <Switch>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/topics">
            <Topics />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

function Home() {
  return <h2>Home</h2>;
}

function About() {
  return <h2>About</h2>;
}

function Topics() {
  let match = useRouteMatch();

  return (
    <div>
      <h2>Topics</h2>

      <ul>
        <li>
          <Link to={`${match.url}/components`}>Components</Link>
        </li>
        <li>
          <Link to={`${match.url}/props-v-state`}>
            Props v. State
          </Link>
        </li>
      </ul>

      {/* The Topics page has its own <Switch> with more routes
          that build on the /topics URL path. You can think of the
          2nd <Route> here as an "index" page for all topics, or
          the page that is shown when no topic is selected */}
      <Switch>
        <Route path={`${match.path}/:topicId`}>
          <Topic />
        </Route>
        <Route path={match.path}>
          <h3>Please select a topic.</h3>
        </Route>
      </Switch>
    </div>
  );
}

function Topic() {
  let { topicId } = useParams();
  return <h3>Requested topic ID: {topicId}</h3>;
}

References

  1. https://github.com/ReactTraining/react-router

  2. https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/philosophy.md

Last modified: 202107081858

JSX

There's currently nothing here.

Backlinks:

Last modified:

NoSQL

There's currently nothing here.

Backlinks:

Last modified:

CSV

There's currently nothing here.

Backlinks:

Last modified:

TSV

There's currently nothing here.

Backlinks:

Last modified:

C

C is a programming language that is very low-level, compiling down to assembly language.

Hello, World

Code

Create a new file called helloworld.c and add this to the contents:

#include <stdio.h>  /* Imports the standard library for IO */

main()  /* defines the function main containing no parameters */
{
    printf("hello, world\n"); /* prints "hello, world" in stdio */
    /* note that the newline must be placed deliberately. C does */
    /* not add a newline with print like Python does. */
}

Compile

Then you want to compile it. The basic compiler found on UNIX computers is cc. Compile it by typing cc helloworld.c. This will create a file called a.out, which is the compiled version of your helloworld.c.

Run It

Run this by typing ./a.out in your shell. You should see hello, world in your terminal.

Basics

Comments

// Single line comment
/* Multiline
   comment */

Constants

Symbolic Constants

Symbolic constants allow the developer to avoid magic numbers and add semantically useful labels to values. This is done using he syntax #define NAME value.

#include <stdio.h>
#define TAXRATE 0.09
#define SERVICECHARGE 2

main()
{
  printf("The tax rate is %1.2f and the service charge is %d", TAXRATE, SERVICECHARGE);
}

/* prints "The tax rate is 0.09 and the service charge is 2"

These statements don't actually do anything in the code. They are handled by the preprocessor and the references to the NAME are simply replaced by the corrseponding value when found. So the above printf line, when eventually seen by the compiler, will be:

printf("The tax rate is %1.2f and the service charge is %d", 0.09, 2);

Enumeration Constants

An enumeration constant is a list of constant integer values. They will start at 0, incrementing on each new constant, unless otherwise defined.

enum boolean { FALSE, TRUE }; // FALSE == 0, TRUE == 1
enum months { JAN = 1, FEB, MAR, ...}; // JAN == 1, FEB == 2...
enum fib { FIRST = 1, SECOND = 1, THIRD,
           FOURTH, FIFTH = 5, SIXTH = 8 } // THIRD == 2, FOURTH == 3...

These constants can be used the same as symbolic constants.

Variables

Variables must be declared before they are used, usually at the beginning before executing your program. They are declared by type and then by name.

int num, step;
char letter;

Variables that exist in and only within a given function are called automatic variables. They come into existence only when the function begins and disappear when the function is finished.

The const keyword may be added to any variable declaration. This means that the variable declared will not change throughout its usage.

External Variables

External variables are defined exactly once outside of any function. This is so that the computer can set aside storage. Within each function that will use that, you will need to declare that variable, and preface that declaration with extern. For instance if max is an external variable, you would declare it within the function as extern int max.

If multiple source files are used, for instance defining X in one file and wanting to use it in another file, the extern declaration is required. If it is all in one file, they can be omitted.

Common practice is to define all external variables in a header file with a .h extension and then #include it in your source files.

Libraries

stdio.h

printf(string, [format, ...])

If you use a format tag in the string, like %d or %c, you will need to add what will replace it in the list of format variables.

int fahr, celsius;
fahr = 100;
celsius = 37;
printf("%d F = %d C", fahr, celsius);
/* prints "100 F = 37 C" */

The format tags can also be accompanied by the minimum width of characters printed.

printf("%3d F = %3d C", fahr, celsius); /* prints "100 F = 37  C" */
printf("%2d F = %2d C", fahr, celsius); /* prints "100 F = 37 C" */

getchar(), putchar(x)

getchar will resolve to a character from stdin, and putchar(x) will put the value of x in stdout.

Sandboxing

You can send text via stdin using printf "123xyz" | ./program.out, with program.out being the name of the compiled program.

You can also use an online REPL, like replit.com.

References

  1. https://hikage.freeshell.org/books/theCprogrammingLanguage.pdf
  2. https://stackoverflow.com/questions/19379353/symbolic-constants-in-c-define-statement

Backlinks:

Last modified: 202108010309

Functions (C)

Basics

Here is the structure of a function definition in C.

/*
return-type function-name(parameter declarations, if any)
{
  declarations
  statements
}
*/

// An example

int add(int m, int n)
{
  int sum;
  sum = m + n;
  return sum;
}

main()

main is a special function that will begin executing when running your compiled file. This must be named main, but other functions can take on whatever other names you'd like.

When a function is invoked within the main function, a function prototype is required to ensure that all invocations and definitions match up.

#include <stdio.h>

int add(int m, int n);
int hooray(void);       // if no params, void is used

int main()
{
  int i;

  for (i = 0; i < 10; ++i)
      printf("%d %d %d\n", i, add(2,i), add(-3,i));
      hooray()
  return 0;
}

int add(int m, int n)
{
  int sum;
  sum = m + n;
  return sum;
}

int hooray()
{
  printf("Hooray!");
}

Last modified: 202107211457

Arrays (C)

Arrays in C, like all things in C, require a lot more care than higher level languages.

Initialization

Arrays are intialized as normal, but followed by n items that should reside in the array: int numbers[n].

You can set the values of each of these items with curly braces.

int array[5] = { 1, 2, 3, 4, 5 };
int zeroArray[10] = { 0 };

In an array of integers, if the list of values within the curly braces is less than the amount needed to fill it completely, all remaining values will resort to zero. Meaning that you can instantiate an array of integers with 0 via int array[n] = { 0 }.

Access/Modification

Arrays can be accessed or modified as normal via square brackets.

int array[8] = { 0 };

array[0] = 100;
array[4] = 500;

Information

Size/Length

The size or length of an array needs some calculation. The built in sizeof function will return the size of an array in bytes, which is not particularly helpful unless you know the size of each cell. So you can use the sizeof function to get the size of the first cell and divide the total size by that value.

#include <stdio.h>

int main() 
{
    int total, single, len;
    int array[10];

    total = sizeof(array);
    single = sizeof(array[0]);
    len = total / single;

    printf("total: %d, single: %d,len: %d", total, single, len);
    // total: 40, single: 4, len: 10

    return 0;
}

Integers that are passed in as arguments will not be able to utilize this technique. The length will need to be calculated ahead of time and passed in as another argument.

#include <stdio.h>

void reverse(char str[], int len);

int main() 
{
    int total, single, len;
    char array[] = "hello";

    total = sizeof(array);
    single = sizeof(array[0]);
    len = total / single;
    printf("%d, %d, %d\n", total, single, len);

    reverse(array, len);

    return 0;
}

void reverse(char str[], int len)
{
  int i;

  for (i = len - 1; i >= 0; i--)
    printf("%c", str[i]);
}

References

  1. https://stackoverflow.com/questions/201101/how-to-initialize-all-members-of-an-array-to-the-same-value

Backlinks:

Last modified: 202107182301

C Data Types

The different data types in C all have their own characteristics.

Since C is strongly typed, certain actions that are intuitive in Javascript or Python may not yield the results you wanted. For instance, if you have variable int x and you try and initialize it with a fractional number, the fractional part will be discarded since x stores an int.

Arrays are intialized as normal, but followed by n items that should reside in the array: int numbers[n].

The following list is only what I've used most and by no means a complete list. Look at the Wikipedia page for more info.

Type Bits Limits Format Description
char 8 -127, +127 %c Used for characters within strings (array of chars)
signed short int 16 -32,767, +32,767 %i Used for numbers and traversing data from stdin
unsigned short int 16 0, +65,535 %u
signed int 16 -2,147,483,648, +2,147,483,647 %i
unsigned int 32 0, +4,294,967,295 %i
signed long int 64 -9,223,372,036,854,775,808, +9,223,372,036,854,775,807 %li
unsigned long int 64 0, +18,446,744,073,709,551,615 %lu
float 32 n/a %f Use for floating point numbers
double 64 n/a %lf Use for really long floating point numbers

Signed/Unsigned

Unsigned numbers are always zero or higher and will have a range of 0 to (2^n) - 1. Signed numbers are negative or positive and have a range of -(2^n-1) to (2^n-1) - 1.

Int

int's can be short or long. Each processor has their own limitations they will choose, but short is always smaller than long, short must be at least 16 bits, and long must be at least 32 bits. It is usually the case that short is 16 bits and long is 32 bits, but the real value on your processor can be found as symbolic constants within the <limits.h> header.

int values can be represented as standard decimal (123), octal (0173), or as hexadecimal (0x7B).

Float

The type long double represents extended-precision floating point. The processor decides the final size of floats and the real values can be found as symbolic constants within the <float.h> header.

References

Last modified: 202108010344

Strings (C)

Strings in C are arrays of characters.

Basics

Both of these strings are arrays of 6 characters in length. These two are the same:

char str1[] = "Hello";
char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'};

Length

The length of a C string is determined by searching for the null termination character, \0.

Syntax

/0

This is the null termination character, signifying the end of the string within the string array.

References

  1. https://stackoverflow.com/questions/14461695/what-does-0-stand-for
  2. https://en.wikipedia.org/wiki/C_string_handling

Last modified: 202107182014

Postgres

Postgres is a relational database management system.

Getting Started

This tutorial will be for getting started with Postgres using node on a Mac.

Local Machine

Installation

Install Postgres using homebrew: brew install postgres

In a new terminal window, start up the local database: postgres -U username -d database_name, filling in the blanks as needed. If this does not work, ensure you have the local database installed at your username. The DB can be also started using brew services start postgres (Be sure to stop the server when completed with your work using brew services stop postgres).

To enter into interactive mode, in your terminal, enter psql. From here, you can enter in any queries you'd like. Ensure they all end with a semicolon, or else you will not get any return back and it will throw.

Initialization

Create a new table in your database: CREATE TABLE numbers( age integer );

Insert a value into the new table: INSERT INTO numbers VALUES (732);

Javascript

Initialize a new npm project, and then install pg, pg-format, and express.

Create a new file in your project called server.js and copy this into it's contents:

const express = require('express'); // Server
var pg = require('pg');             // Postgres 
var format = require('pg-format');  // For dynamic SQL queries (a la MySQL ?)

const app = express();              // Start your server

var PGUSER = '<your username>';     // Definte the username and database
var PGDATABASE = '<your username>'; // previously set up in Postgres.

var age = 732;                      // Used so we can reference our earlier insertion.

var config = {
  user: PGUSER,
  database: PGDATABASE,
  max: 10,                          // max number of clients in the pool
  idleTimeoutMillis: 30000          // how long a client is allowed to remain idle before being closed
};

var pool = new pg.Pool(config);     // Create a new connection instance

pool.connect(function (err, client, done) { // Connect to the DB
  if (err) {
    console.log(err);
  }
  app.listen(3000, function () {     // Connect to the Express server
    console.log('listening on 3000')
  });
  // Build a dynamic query using `age`
  var ageQuery = format('SELECT * from numbers WHERE age = %L', age);
  // Query the DB for all rows from the numbers table where age is = 732
  client.query(ageQuery, function (err, result) {
    if (err) {
      console.log(err);
    }
    console.log(result.rows[0]);
  });
});

Now in your terminal, run node server.js and assuming the database is still running, if should return:

listening on 3000
{ age: 732 }

Schemas

Schemas are within a database but are ways of organizing tables, objects, functions, etc. within the database. In a database with table1, table2, and table3, a schema could hold table1 and table2, with another schema holding table2 and table3.

To create a schema, use CREATE SCHEMA name, followed by the other components.

CREATE SCHEMA schema_example
  CREATE TABLE people(
    id INT PRIMARY KEY,
    name TEXT NOT NULL,
    age INT,
    birthday DATE
  )
  CREATE VIEW john_club AS
    SELECT 
      *
    FROM
      people
    WHERE
      name = 'John';

Querying JSONB Columns

SELECT
  column_name -> 'property_name' AS display_name
FROM
  table_name;

Commands

Command Description
\dt Display all tables in the database
TABLE x Show the contents of table x.
SELECT schema_name FROM information_schema.schemata; Show all schema in a given database

References

  1. https://hub.packtpub.com/how-setup-postgresql-nodejs/
  2. https://www.postgresqltutorial.com/postgresql-show-tables/
  3. https://www.postgresqltutorial.com/postgresql-create-schema/
  4. https://www.guru99.com/postgresql-view.html
  5. https://gist.github.com/Kartones/dd3ff5ec5ea238d4c546
  6. https://www.postgresqltutorial.com/postgresql-cheat-sheet/
  7. https://kb.objectrocket.com/postgresql/how-to-query-a-postgres-jsonb-column-1433

Last modified: 202107301943

Common SQL Queries

These are some common SQL queries that come up. All ? symbols represent a place where you would dynamically insert info, like with Node's MySQL module.

Retrieval

Get the info from all rows with a given email

SELECT * FROM example_table
  WHERE email = ?;

See if more than one entry exists with a given email

SELECT email, COUNT(email) 
  FROM example_table
  GROUP BY email
  HAVING COUNT(email) > 1;

References

Backlinks:

Last modified: 202105310620