mirror of
https://github.com/Brandon-Rozek/website.git
synced 2024-11-28 17:03:39 -05:00
Added old URL paths as aliases and cleaned up some code sections of old posts
This commit is contained in:
parent
8e175e60e4
commit
b86c103ade
27 changed files with 1023 additions and 966 deletions
|
@ -1,89 +1,79 @@
|
|||
---
|
||||
id: 57
|
||||
title: Responsive Layout and Animation
|
||||
date: 2015-04-16T22:19:36+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: http://brandonrozek.com/?p=57
|
||||
permalink: /2015/04/responsive-layout-and-animation/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
dsq_thread_id:
|
||||
- "3688354609"
|
||||
- "3688354609"
|
||||
mf2_cite:
|
||||
- 'a:1:{s:6:"author";a:0:{}}'
|
||||
- 'a:1:{s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "135656876494"
|
||||
- "135656876494"
|
||||
kind:
|
||||
- article
|
||||
---
|
||||
I saw [Mike Riethmuller’s](http://madebymike.com.au/) precision typography [pen](http://codepen.io/MadeByMike/pen/YPJJYv){.broken_link}, and was highly impressed. I think the equation used has other purposes as well
|
||||
|
||||
<!--more-->
|
||||
|
||||
Side Note: I changed the form of the equation to something similar to y = mx + b so that I can more easily recognize how it functions
|
||||
|
||||
#### Responsive Layout
|
||||
|
||||
There are many occasions where I want an element on the page to move between two points. The navigation in the header of my site (at the time of writing) is a great example of this. So knowing the two points I want it to lie between and having the screen width as the variable, I can plug in… [<img class="aligncenter size-full wp-image-58" src="https://brandonrozek.com/wp-content/uploads/2015/04/responsivelayoutequation.gif" alt="f(x) = (100 * (b - a)/(d - c))X + (ad - bc) / (d - c)" width="219" height="36" />](https://brandonrozek.com/wp-content/uploads/2015/04/responsivelayoutequation.gif){.broken_link} where a is the start pixel b is the end pixel c is the start media query d is the end media query and X is the screen width out of 100 otherwise known as 1vw \*\*Don’t forget to keep track of your units!! Whether it’s px/rem/em/etc.\*\* Say I want to push a box towards the right a minimum of 5px, a maximum of 20px and for the push to vary between the widths 400-800px. Then I would write…
|
||||
|
||||
<pre><code class="language-css">
|
||||
---
|
||||
id: 57
|
||||
title: Responsive Layout and Animation
|
||||
date: 2015-04-16T22:19:36+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: http://brandonrozek.com/?p=57
|
||||
aliases:
|
||||
- /2015/04/responsive-layout-and-animation/
|
||||
permalink: /2015/04/responsive-layout-and-animation/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
dsq_thread_id:
|
||||
- "3688354609"
|
||||
- "3688354609"
|
||||
mf2_cite:
|
||||
- 'a:1:{s:6:"author";a:0:{}}'
|
||||
- 'a:1:{s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "135656876494"
|
||||
- "135656876494"
|
||||
kind:
|
||||
- article
|
||||
---
|
||||
I saw [Mike Riethmuller’s](http://madebymike.com.au/) precision typography [pen](http://codepen.io/MadeByMike/pen/YPJJYv){.broken_link}, and was highly impressed. I think the equation used has other purposes as well
|
||||
|
||||
<!--more-->
|
||||
|
||||
Side Note: I changed the form of the equation to something similar to y = mx + b so that I can more easily recognize how it functions
|
||||
|
||||
#### Responsive Layout
|
||||
|
||||
There are many occasions where I want an element on the page to move between two points. The navigation in the header of my site (at the time of writing) is a great example of this. So knowing the two points I want it to lie between and having the screen width as the variable, I can plug in… [<img class="aligncenter size-full wp-image-58" src="https://brandonrozek.com/wp-content/uploads/2015/04/responsivelayoutequation.gif" alt="f(x) = (100 * (b - a)/(d - c))X + (ad - bc) / (d - c)" width="219" height="36" />](https://brandonrozek.com/wp-content/uploads/2015/04/responsivelayoutequation.gif){.broken_link} where a is the start pixel b is the end pixel c is the start media query d is the end media query and X is the screen width out of 100 otherwise known as 1vw \*\*Don’t forget to keep track of your units!! Whether it’s px/rem/em/etc.\*\* Say I want to push a box towards the right a minimum of 5px, a maximum of 20px and for the push to vary between the widths 400-800px. Then I would write…
|
||||
|
||||
```css
|
||||
@media (min-width: 400px) and (max-width: 800px) {
|
||||
|
||||
.box {
|
||||
|
||||
position: relative;
|
||||
|
||||
left: calc(3.75vw - 10px) /*After simplifying the equation*/ }
|
||||
|
||||
.box {
|
||||
position: relative;
|
||||
left: calc(3.75vw - 10px) /*After simplifying the equation*/
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
That would only make it vary between 400-800px. Now we need to include what happens under 400px and over 800px.
|
||||
|
||||
<pre><code class="language-css">
|
||||
```
|
||||
|
||||
That would only make it vary between 400-800px. Now we need to include what happens under 400px and over 800px.
|
||||
|
||||
```css
|
||||
@media (max-width: 400px) {
|
||||
|
||||
.box {
|
||||
|
||||
position: relative;
|
||||
|
||||
left: 5px; }
|
||||
|
||||
.box {
|
||||
position: relative;
|
||||
left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 400px) and (max-width: 800px) {
|
||||
|
||||
.box {
|
||||
|
||||
position: relative;
|
||||
|
||||
left: calc(3.75vw - 10px); }
|
||||
|
||||
.box {
|
||||
position: relative;
|
||||
left: calc(3.75vw - 10px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
|
||||
.box {
|
||||
|
||||
position: relative;
|
||||
|
||||
left: 20px; }
|
||||
|
||||
.box {
|
||||
position: relative;
|
||||
left: 20px;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
This is exactly like Mike’s pen, but instead he uses the equation to adjust the font-size between an upper and lower bound. You can apply this method to anything that accepts calc() and viewport units. Here is my [pen](http://codepen.io/brandonrozek/pen/JoQVEb){.broken_link} showing some use cases. To make your life easier, I made a quick little tool where you can input the variables and it will provide you with a simpler form of the equation to put into your calc() function [here](http://codepen.io/brandonrozek/pen/KpPwGL){.broken_link}.
|
||||
|
||||
#### Animation
|
||||
|
||||
This is where the majority of my research went towards. It’s not as practical as say positioning an element is but I find it interesting. Like, what if I can manipulate the acceleration of the function? [<img class="aligncenter size-full wp-image-62" src="https://brandonrozek.com/wp-content/uploads/2015/04/accelerationequation.gif" alt="f(x) = ((b - a) / (d^n - c^n))X^n + (ad^n - bc^n) / (d^n - c^n) " width="202" height="36" />](https://brandonrozek.com/wp-content/uploads/2015/04/accelerationequation.gif){.broken_link} Where a is the start unit b is the end unit c is the start time d is the end time n is the acceleration modifier and X is time The interesting part of the function here is the n. If I keep n at 1, then the acceleration is constant. If it’s less than one, then it’s fast in the beginning and slows down at the end. If it’s greater than one, then it’s the opposite. I also made a little pen [here](http://codepen.io/brandonrozek/pen/RNzdOV){.broken_link} to demo this for you.
|
||||
|
||||
#### Conclusion
|
||||
|
||||
```
|
||||
|
||||
This is exactly like Mike’s pen, but instead he uses the equation to adjust the font-size between an upper and lower bound. You can apply this method to anything that accepts calc() and viewport units. Here is my [pen](http://codepen.io/brandonrozek/pen/JoQVEb){.broken_link} showing some use cases. To make your life easier, I made a quick little tool where you can input the variables and it will provide you with a simpler form of the equation to put into your calc() function [here](http://codepen.io/brandonrozek/pen/KpPwGL){.broken_link}.
|
||||
|
||||
#### Animation
|
||||
|
||||
This is where the majority of my research went towards. It’s not as practical as say positioning an element is but I find it interesting. Like, what if I can manipulate the acceleration of the function? [<img class="aligncenter size-full wp-image-62" src="https://brandonrozek.com/wp-content/uploads/2015/04/accelerationequation.gif" alt="f(x) = ((b - a) / (d^n - c^n))X^n + (ad^n - bc^n) / (d^n - c^n) " width="202" height="36" />](https://brandonrozek.com/wp-content/uploads/2015/04/accelerationequation.gif){.broken_link} Where a is the start unit b is the end unit c is the start time d is the end time n is the acceleration modifier and X is time The interesting part of the function here is the n. If I keep n at 1, then the acceleration is constant. If it’s less than one, then it’s fast in the beginning and slows down at the end. If it’s greater than one, then it’s the opposite. I also made a little pen [here](http://codepen.io/brandonrozek/pen/RNzdOV){.broken_link} to demo this for you.
|
||||
|
||||
#### Conclusion
|
||||
|
||||
Having a function that goes between two points is incredibly handy. Now when it comes to positioning, I don’t have to guess which values match the design. If i cant something to be between here and there fluidly, I can do it. What about animation? Chaining them together should have an interesting affect… P.S For those of you crazy people who like to see the theory behind the math, (like myself) I have my scanned work [here](https://brandonrozek.com/2015/04/function-two-points-theory/).
|
|
@ -5,6 +5,8 @@ date: 2015-05-23T19:59:25+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: http://brandonrozek.com/?p=85
|
||||
aliases:
|
||||
- /2015/05/animatable-border/
|
||||
permalink: /2015/05/animatable-border/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -34,21 +36,16 @@ This post follows well along with my Codepen [demo](http://codepen.io/brandonroz
|
|||
|
||||
Border-color animates by splitting the colors to their red, green and blue components and raises/lowers them to it’s new value. ([Demo](http://codepen.io/brandonrozek/pen/PqzPMe){.broken_link}) ([Spec](http://www.w3.org/TR/css3-transitions/#animtype-color)) Example of animation corresponds to #1 in the pen, but I will rewrite the relevant code here.
|
||||
|
||||
<pre><code class="language-css">
|
||||
```css
|
||||
@keyframes color {
|
||||
|
||||
to { border-color: purple red green blue; }
|
||||
|
||||
to { border-color: purple red green blue; }
|
||||
}
|
||||
|
||||
.border-color {
|
||||
|
||||
border-color: white;
|
||||
|
||||
animation: color .4s ease-in .1s infinite alternate;
|
||||
|
||||
border-color: white;
|
||||
animation: color .4s ease-in .1s infinite alternate;
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -58,44 +55,31 @@ animation: color .4s ease-in .1s infinite alternate;
|
|||
* Each value corresponds to a corner starting from the top left and going clockwise
|
||||
* Initial Value: 0
|
||||
|
||||
<pre><code class="language-css">
|
||||
```css
|
||||
.border-radius {
|
||||
|
||||
border-radius: 40% 30% 60% 50% / 20% 40% 60% 80%;
|
||||
|
||||
/** is the same as **/
|
||||
|
||||
border-top-left-radius: 40% 20%;
|
||||
|
||||
border-top-right-radius: 30% 40%;
|
||||
|
||||
border-bottom-right-radius: 60% 60%;
|
||||
|
||||
border-bottom-left-radius: 50% 80%;
|
||||
|
||||
/** where the first value is the horizontal radius and the second value the vertical radius**/
|
||||
|
||||
border-radius: 40% 30% 60% 50% / 20% 40% 60% 80%;
|
||||
/** is the same as **/
|
||||
border-top-left-radius: 40% 20%;
|
||||
border-top-right-radius: 30% 40%;
|
||||
border-bottom-right-radius: 60% 60%;
|
||||
border-bottom-left-radius: 50% 80%;
|
||||
/** where the first value is the horizontal
|
||||
radius and the second value the vertical radius **/
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
For animation, this corresponds to #2 in the pen I made at the top. I’ll repeat the relevant code here.
|
||||
|
||||
<pre><code class="language-css">
|
||||
|
||||
```css
|
||||
@keyframes radius {
|
||||
|
||||
to { border-radius: 20%; }
|
||||
|
||||
to { border-radius: 20%; }
|
||||
}
|
||||
|
||||
.border-radius {
|
||||
|
||||
border-radius: 0;
|
||||
|
||||
animation: radius .5s ease-in .1s infinite alternate;
|
||||
|
||||
border-radius: 0;
|
||||
animation: radius .5s ease-in .1s infinite alternate;
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -107,24 +91,27 @@ animation: radius .5s ease-in .1s infinite alternate;
|
|||
|
||||
For animation, this corresponds to #3 in the pen I made at the top. I’ll repeat the relevant code here.
|
||||
|
||||
<pre><code class="language-css">
|
||||
```css
|
||||
@keyframes width {
|
||||
|
||||
to { border-width: .15rem .25rem .15rem .25rem; }
|
||||
|
||||
to { border-width: .15rem .25rem .15rem .25rem; }
|
||||
}
|
||||
|
||||
.border-width {
|
||||
|
||||
border-width: .7rem;
|
||||
|
||||
animation: width .5s ease-in .1s infinite alternate;
|
||||
|
||||
border-width: .7rem;
|
||||
animation: width .5s ease-in .1s infinite alternate;
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Conclusion
|
||||
|
||||
Animations are quite enjoyable. The last box in my Codepen demo tries combining all three of those animations. (Super Wacky!) You don’t need to use keyframe animations to achieve this, you can also use the transition property. I used keyframes so you can better visualize what’s going on. There are plenty of other animatable properties to go through, so I’ll get started on those. In the meantime, if you want to look at some of the sites I used for research I’ll include the links below. <https://developer.mozilla.org/en-US/docs/Web/CSS/animation> <http://www.w3.org/TR/css3-transitions/#animatable-css> <https://developer.mozilla.org/en-US/docs/Web/CSS/border-color> <https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius> <https://developer.mozilla.org/en-US/docs/Web/CSS/border-width> <https://docs.webplatform.org/wiki/css/properties/border-color>{.broken_link} <https://docs.webplatform.org/wiki/css/properties/border-radius>{.broken_link} <https://docs.webplatform.org/wiki/css/properties/border-width>{.broken_link}
|
||||
Animations are quite enjoyable. The last box in my Codepen demo tries combining all three of those animations. (Super Wacky!) You don’t need to use keyframe animations to achieve this, you can also use the transition property. I used keyframes so you can better visualize what’s going on. There are plenty of other animatable properties to go through, so I’ll get started on those. In the meantime, if you want to look at some of the sites I used for research I’ll include the links below.
|
||||
- <https://developer.mozilla.org/en-US/docs/Web/CSS/animation>
|
||||
- <http://www.w3.org/TR/css3-transitions/#animatable-css>
|
||||
- <https://developer.mozilla.org/en-US/docs/Web/CSS/border-color>
|
||||
- <https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius>
|
||||
- <https://developer.mozilla.org/en-US/docs/Web/CSS/border-width>
|
||||
- <https://docs.webplatform.org/wiki/css/properties/border-color>{.broken_link}
|
||||
- <https://docs.webplatform.org/wiki/css/properties/border-radius>{.broken_link}
|
||||
- <https://docs.webplatform.org/wiki/css/properties/border-width>{.broken_link}
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2015-09-14T12:07:52+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=155
|
||||
aliases:
|
||||
- /2015/09/animatable-box-model/
|
||||
permalink: /2015/09/animatable-box-model/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2015-10-03T09:34:08+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=190
|
||||
aliases:
|
||||
- /2015/10/animatable-location/
|
||||
permalink: /2015/10/animatable-location/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -44,7 +46,7 @@ Background-position sets where the background is relative to it’s backgrou
|
|||
|
||||
<pre><code class="language-css">
|
||||
@keyframes background-position {
|
||||
|
||||
|
||||
to { background-position: 100% 0%; }
|
||||
|
||||
}
|
||||
|
@ -78,7 +80,7 @@ The left, right, top, and bottom properties require the position to be set to so
|
|||
25% {
|
||||
|
||||
top: 0;
|
||||
|
||||
|
||||
left: 3rem;
|
||||
|
||||
}
|
||||
|
@ -86,7 +88,7 @@ The left, right, top, and bottom properties require the position to be set to so
|
|||
50% {
|
||||
|
||||
top: 3rem;
|
||||
|
||||
|
||||
left: 3rem;
|
||||
|
||||
}
|
||||
|
@ -94,7 +96,7 @@ The left, right, top, and bottom properties require the position to be set to so
|
|||
75% {
|
||||
|
||||
top: 3rem;
|
||||
|
||||
|
||||
left: 0;
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2015-10-03T08:44:51+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=148
|
||||
aliases:
|
||||
- /2015/10/animatable-text/
|
||||
permalink: /2015/10/animatable-text/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -38,7 +40,7 @@ Line-height is the space between each line in a text block. It is commonly recom
|
|||
to {
|
||||
|
||||
opacity: 1;
|
||||
|
||||
|
||||
line-height: 1.2;
|
||||
|
||||
}
|
||||
|
@ -120,9 +122,9 @@ Text-shadow applies a shadow to both the text and it’s text-decoration. Mu
|
|||
.text-shadow {
|
||||
|
||||
font-size: 1.5rem;
|
||||
|
||||
|
||||
text-shadow: -10px 5px 3.5px rgba(0, 0, 0, .3);
|
||||
|
||||
|
||||
animation: text-shadow 1s ease 0s infinite;
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2015-10-04T17:50:50+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=210
|
||||
aliases:
|
||||
- /2015/10/html-css-javascript-link-together/
|
||||
permalink: /2015/10/html-css-javascript-link-together/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2015-10-10T20:01:20+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=238
|
||||
aliases:
|
||||
- /2015/10/javascript-data-types/
|
||||
permalink: /2015/10/javascript-data-types/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -41,7 +43,7 @@ You can access a character inside of a string by using [] notation. Inside the [
|
|||
<td>
|
||||
B
|
||||
</td>
|
||||
|
||||
|
||||
<td>
|
||||
r
|
||||
</td>
|
||||
|
@ -66,7 +68,7 @@ You can access a character inside of a string by using [] notation. Inside the [
|
|||
n
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
</td>
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2015-10-11T16:52:36+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=297
|
||||
aliases:
|
||||
- /2015/10/animatable-visual/
|
||||
permalink: /2015/10/animatable-visual/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2015-10-18T16:32:37+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=337
|
||||
aliases:
|
||||
- /2015/10/animatable-transform/
|
||||
permalink: /2015/10/animatable-transform/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2015-10-18T18:30:21+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=344
|
||||
aliases:
|
||||
- /2015/10/javascript-conditional-statements/
|
||||
permalink: /2015/10/javascript-conditional-statements/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -32,25 +34,28 @@ This post is part of my lecture series for Math I/O. There is no pre-reading for
|
|||
|
||||
To run a block of code when a condition is true, use an <code class="language-javascript">if</code> statement.
|
||||
|
||||
<pre><code class="language-javascript"> if (condition) {
|
||||
```javascript
|
||||
if (condition) {
|
||||
doSomething();
|
||||
}
|
||||
</code></pre>
|
||||
}
|
||||
```
|
||||
|
||||
You can also run a block of code when a condition is false using the <code class="language-javascript">else</code> statement.
|
||||
|
||||
<pre><code class="language-javascript"> if (condition) {
|
||||
doSomething();
|
||||
} else {
|
||||
doSomethingElse();
|
||||
}
|
||||
</code></pre>
|
||||
```javascript
|
||||
if (condition) {
|
||||
doSomething();
|
||||
} else {
|
||||
doSomethingElse();
|
||||
}
|
||||
```
|
||||
|
||||
### <a href="#switch-statement" name="switch-statement"></a>Switch statement {#switch-statement}
|
||||
|
||||
If you want to check a variable for **equality** against multiple different cases, use a <code class="language-javascript">switch</code> statement.
|
||||
|
||||
<pre><code class="language-javascript"> switch (variable) {
|
||||
```javascript
|
||||
switch (variable) {
|
||||
case condition1:
|
||||
doSomething();
|
||||
break;
|
||||
|
@ -60,8 +65,8 @@ If you want to check a variable for **equality** against multiple different case
|
|||
default:
|
||||
doSomethingCompletelyDifferent();
|
||||
break;
|
||||
}
|
||||
</code></pre>
|
||||
}
|
||||
```
|
||||
|
||||
The default statement runs when the variable doesn’t equal any of the cases.
|
||||
|
||||
|
@ -69,10 +74,11 @@ The default statement runs when the variable doesn’t equal any of the cases.
|
|||
|
||||
To run a block of code over and over again until a condition is false, use a <code class="language-javascript">while</code> loop.
|
||||
|
||||
<pre><code class="language-javascript"> while (condition) {
|
||||
doSomething();
|
||||
}
|
||||
</code></pre>
|
||||
```javascript
|
||||
while (condition) {
|
||||
doSomething();
|
||||
}
|
||||
```
|
||||
|
||||
Don’t forget to include something in the loop that will eventually make the condition <code class="language-javascript">false</code>, otherwise you run into an infinite loop. (Which is a loop that never stops repeating itself; most likely crashing your browser)
|
||||
|
||||
|
@ -80,10 +86,11 @@ Don’t forget to include something in the loop that will eventually make the co
|
|||
|
||||
If you want to run something a certain amount of times, use a “<code class="language-javascript">for"</code> loop. For loops can be broken down into three components: an initiating statement, a condition, and a statement that runs after every loop.
|
||||
|
||||
<pre><code class="language-javascript"> for (var i = 0; i < 5; i++) {
|
||||
```javascript
|
||||
for (var i = 0; i < 5; i++) {
|
||||
doSomething();
|
||||
}
|
||||
</code></pre>
|
||||
}
|
||||
```
|
||||
|
||||
Here you have the initiating statement of <code class="language-javascript">var i = 0</code>. From there you check, is <code class="language-javascript">i</code> less than 5? Yes, so then we <code class="language-javascript">doSomething();</code>. After we <code class="language-javascript">doSomething();</code>, we add 1 to <code class="language-javascript">i</code>. Now <code class="language-javascript">i</code> equals 2. Is <code class="language-javascript">i</code> still less than 5? Yes, so we <code class="language-javascript">doSomething();</code>. Then we add 1 to <code class="language-javascript">i</code> again. This loop will keep happening until <code class="language-javascript">i</code> is not less than 5.
|
||||
|
||||
|
@ -91,11 +98,12 @@ Here you have the initiating statement of <code class="language-javascript">var
|
|||
|
||||
Having different control/conditional statements helps keep the state of any application you’re making. Did the user say not to notify them? Then don’t, otherwise (else) notify them. That’s all I have to say for this week. Hope this post helps you get a little more used to this big world called programming.
|
||||
|
||||
<pre><code class="language-javascript"> if (youLikeThisPost) {
|
||||
```javascript
|
||||
if (youLikeThisPost) {
|
||||
console.log("Come back next week! :)");
|
||||
} else {
|
||||
console.log("Aww that's okay, you should give me another chance next week :)");
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
I recommend that you look at different perspectives of the same concepts. WebCheatSheet.com has a similar post to mine, check out what they had to say [here](http://webcheatsheet.com/javascript/if_else_switch.php).
|
|
@ -5,6 +5,8 @@ date: 2015-10-25T13:48:41+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=350
|
||||
aliases:
|
||||
- /2015/10/functions/
|
||||
permalink: /2015/10/functions/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -27,33 +29,33 @@ Ever had a snippet of code that appears multiple times in different places in yo
|
|||
|
||||
To make a function
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var doSomething = function() {
|
||||
doStuff;
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
To call the above function to execute
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
doSomething();
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
### <a href="#arguments" name="arguments"></a>Arguments {#arguments}
|
||||
|
||||
You can also add in arguments (parameters that go inside the paraenthesis next to the word function) for the functions to use.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var add = function(number1, number2) {
|
||||
return number1 + number2;
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
And when you use the `return` keyword, like the function above. You can store the value in a variable for future use.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var total = add(1, 3);
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
<code class="language-javascript">total</code> here will equal `4`
|
||||
|
||||
|
@ -63,16 +65,16 @@ Functions create their own scope, which means that variables created inside the
|
|||
|
||||
The snippet below will output an error like <code class="language-javascript">total is not defined</code>
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var add = function(number1, number2) {
|
||||
var total = number1 + number2;
|
||||
}
|
||||
console.log(total);
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
Below is a correct example of the concept
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
//Function below converts km/hr to m/s
|
||||
var convert = function(speed) {
|
||||
var metersPerHour = speed * 1000;
|
||||
|
@ -80,13 +82,13 @@ Below is a correct example of the concept
|
|||
return metersPerSecond;
|
||||
}
|
||||
var currentSpeed = convert(5);
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
It’s also important to note that functions can use variables outside of it; granted it resides in the same scope.
|
||||
|
||||
Here is an example of a variable that doesn’t reside in the same scope as the function. (The below code will fail)
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var something = function() {
|
||||
var x = 5;
|
||||
var y = 2;
|
||||
|
@ -96,17 +98,17 @@ Here is an example of a variable that doesn’t reside in the same scope as
|
|||
console.log(x + y);
|
||||
}
|
||||
addXandY();
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
Below, is an example of where the variable does reside in the same scope as the function. Which allows this snippet to execute properly.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var x = 5;
|
||||
var addX = function(a) {
|
||||
return a + x;
|
||||
}
|
||||
var sum = addX(6);
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
<code class="language-javascript">sum</code> here will equal <code class="language-javascript">11</code>
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2015-11-14T15:47:06+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=400
|
||||
aliases:
|
||||
- /2015/11/service-workers/
|
||||
permalink: /2015/11/service-workers/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -33,34 +35,37 @@ You need HTTPS to be able to use service workers on your site. This is mainly fo
|
|||
|
||||
Place `service-worker.js` on the root of your site. This is so the service worker can access all the files in the site. Then in your main javascript file, register the service worker.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
if (navigator.serviceWorker) {
|
||||
navigator.serviceWorker.register('/serviceworker.js', {
|
||||
scope: '/'
|
||||
});
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
## <a href="#install-the-service-worker" name="install-the-service-worker"></a>Install the service worker {#install-the-service-worker}
|
||||
|
||||
The first time the service worker runs, it emits the `install` event. At this time, we can load the visitor’s cache with some resources for when they’re offline. Every so often, I like to change up the theme of the site. So I have version numbers attached to my files. I would also like to invalidate my cache with this version number. So at the top of the file I added
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var version = 'v2.0.24:';
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
Now, to specify which files I want the service worker to cache for offline use. I thought my home page and my offline page would be good enough.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var offlineFundamentals = [
|
||||
'/',
|
||||
'/offline/'
|
||||
];
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
Since <code class="language-javascript">cache.addAll()</code> hasn’t been implemented yet in any of the browsers, and the polyfill implementation didn’t work for my needs. I pieced together my own.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var updateStaticCache = function() {
|
||||
return caches.open(version + 'fundamentals').then(function(cache) {
|
||||
return Promise.all(offlineFundamentals.map(function(value) {
|
||||
|
@ -76,7 +81,8 @@ var updateStaticCache = function() {
|
|||
}))
|
||||
})
|
||||
};
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
Let’s go through this chunk of code.
|
||||
|
||||
|
@ -88,11 +94,12 @@ Let’s go through this chunk of code.
|
|||
|
||||
Now we call it when the `install` event is fired.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
self.addEventListener("install", function(event) {
|
||||
event.waitUntil(updateStaticCache())
|
||||
})
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
With this we now cached all the files in the offlineFundamentals array during the install step.
|
||||
|
||||
|
@ -100,7 +107,7 @@ With this we now cached all the files in the offlineFundamentals array during th
|
|||
|
||||
Since we’re caching everything. If you change one of the files, your visitor wouldn’t get the changed file. Wouldn’t it be nice to remove old files from the visitor’s cache? Every time the service worker finishes the install step, it releases an `activate` event. We can use this to look and see if there are any old cache containers on the visitor’s computer. From [Nicolas’ code](https://ponyfoo.com/articles/serviceworker-revolution). Thanks for sharing 🙂
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var clearOldCaches = function() {
|
||||
return caches.keys().then(function(keys) {
|
||||
return Promise.all(
|
||||
|
@ -114,7 +121,8 @@ var clearOldCaches = function() {
|
|||
);
|
||||
})
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
1. Check the names of each of the cache containers
|
||||
2. If they don’t start with the correct version number
|
||||
|
@ -122,11 +130,12 @@ var clearOldCaches = function() {
|
|||
|
||||
Call the function when the `activate` event fires.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
self.addEventListener("activate", function(event) {
|
||||
event.waitUntil(clearOldCaches())
|
||||
});
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
## <a href="#intercepting-fetch-requests" name="intercepting-fetch-requests"></a>Intercepting fetch requests {#intercepting-fetch-requests}
|
||||
|
||||
|
@ -136,7 +145,7 @@ The cool thing about service worker’s is that it can handle file requests. We
|
|||
|
||||
If the visitor started browsing all of the pages on my site, his or her cache would start to get bloated with files. To not burden my visitors, I decided to only keep the latest 25 pages and latest 10 images in the cache.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var limitCache = function(cache, maxItems) {
|
||||
cache.keys().then(function(items) {
|
||||
if (items.length > maxItems) {
|
||||
|
@ -144,7 +153,8 @@ var limitCache = function(cache, maxItems) {
|
|||
}
|
||||
})
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
We’ll call it later in the code.
|
||||
|
||||
|
@ -152,7 +162,7 @@ We’ll call it later in the code.
|
|||
|
||||
Every time I fetch a file from the network I throw it into a specific cache container. <code class="language-javascript">'pages'</code> for HTML files, <code class="language-javascript">'images'</code> for CSS files, and <code class="language-javascript">'assets'</code> for any other file. This is so I can handle the cache limiting above easier. Defined within the `fetch` event.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var fetchFromNetwork = function(response) {
|
||||
var cacheCopy = response.clone();
|
||||
if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
|
||||
|
@ -172,16 +182,15 @@ var fetchFromNetwork = function(response) {
|
|||
cache.put(event.request, cacheCopy);
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
### <a href="#when-the-network-fails" name="when-the-network-fails"></a>When the network fails {#when-the-network-fails}
|
||||
|
||||
There are going to be times where the visitor cannot access the website. Maybe they went in a tunnel while they were riding a train? Or maybe your site went down. I thought it would be nice for my reader’s to be able to look over my blog posts again regardless of an internet connection. So I provide a fall-back. Defined within the `fetch` event.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var fallback = function() {
|
||||
if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
|
||||
return caches.match(event.request).then(function (response) {
|
||||
|
@ -191,7 +200,8 @@ var fallback = function() {
|
|||
return new Response('<svg width="400" height="300" role="img" aria-labelledby="offline-title" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title id="offline-title">Offline</title><g fill="none" fill-rule="evenodd"><path fill="#D8D8D8" d="M0 0h400v300H0z"/><text fill="#9B9B9B" font-family="Helvetica Neue,Arial,Helvetica,sans-serif" font-size="72" font-weight="bold"><tspan x="93" y="172">offline</tspan></text></g></svg>', { headers: { 'Content-Type': 'image/svg+xml' }});
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
1. Is the request for a HTML file?
|
||||
* Show the [offline](https://brandonrozek.com/offline/) page.
|
||||
|
@ -202,20 +212,22 @@ var fallback = function() {
|
|||
|
||||
First off, I’m only handling GET requests.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
if (event.request.method != 'GET') {
|
||||
return;
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
For HTML files, grab the file from the network. If that fails, then look for it in the cache. _Network then cache strategy_
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
|
||||
event.respondWith(fetch(event.request).then(fetchFromNetwork, fallback));
|
||||
return;
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
For non-HTML files, follow this series of steps
|
||||
|
||||
|
@ -226,13 +238,14 @@ For non-HTML files, follow this series of steps
|
|||
|
||||
_Cache then network strategy_
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
event.respondWith(
|
||||
caches.match(event.request).then(function(cached) {
|
||||
return cached || fetch(event.request).then(fetchFromNetwork, fallback);
|
||||
})
|
||||
)
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
|
||||
For different stategy’s, take a look at Jake Archibald’s [offline cookbook](https://jakearchibald.com/2014/offline-cookbook/).
|
||||
|
||||
|
@ -240,7 +253,7 @@ For different stategy’s, take a look at Jake Archibald’s [offline cookbook](
|
|||
|
||||
With all of that, we now have a fully functioning offline-capable website! I wouldn’t be able to implement this myself if it wasn’t for some of the awesome people I mentioned earlier sharing their experience. So share, share, share! With that sentiment, I’ll now share the full code for `service-worker.js` **Update:** There is a new version of this code over at this [blog post](https://brandonrozek.com/2015/11/limiting-cache-service-workers-revisited/).
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var version = 'v2.0.24:';
|
||||
|
||||
var offlineFundamentals = [
|
||||
|
@ -321,10 +334,10 @@ self.addEventListener("fetch", function(event) {
|
|||
cache.put(event.request, cacheCopy);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
//Fetch from network failed
|
||||
var fallback = function() {
|
||||
if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
|
||||
|
@ -335,18 +348,18 @@ self.addEventListener("fetch", function(event) {
|
|||
return new Response('<svg width="400" height="300" role="img" aria-labelledby="offline-title" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title id="offline-title">Offline</title><g fill="none" fill-rule="evenodd"><path fill="#D8D8D8" d="M0 0h400v300H0z"/><text fill="#9B9B9B" font-family="Helvetica Neue,Arial,Helvetica,sans-serif" font-size="72" font-weight="bold"><tspan x="93" y="172">offline</tspan></text></g></svg>', { headers: { 'Content-Type': 'image/svg+xml' }});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This service worker won't touch non-get requests
|
||||
if (event.request.method != 'GET') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//For HTML requests, look for file in network, then cache if network fails.
|
||||
if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
|
||||
event.respondWith(fetch(event.request).then(fetchFromNetwork, fallback));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//For non-HTML requests, look for file in cache, then network if no cache exists.
|
||||
event.respondWith(
|
||||
caches.match(event.request).then(function(cached) {
|
||||
|
@ -359,4 +372,4 @@ self.addEventListener("fetch", function(event) {
|
|||
self.addEventListener("activate", function(event) {
|
||||
event.waitUntil(clearOldCaches())
|
||||
});
|
||||
</code></pre>
|
||||
```
|
|
@ -5,6 +5,8 @@ date: 2015-11-15T12:46:14+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=398
|
||||
aliases:
|
||||
- /2015/11/fractions-js/
|
||||
permalink: /2015/11/fractions-js/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -36,12 +38,12 @@ I broke up each fraction into two things, a numerator and a denominator. With th
|
|||
For addition, if two fractions have the same denominator, then you just need to add the numerators.
|
||||
|
||||
1/3 + 1/3 = 2/3
|
||||
|
||||
|
||||
|
||||
If not, then you need to change it to have a common denominator. We can do this by multiply each fractions numerator and denominator by the other fractions denominator.
|
||||
|
||||
1/2 + 1/3 = (1 * 3)/ (2 * 3) + (1 * 2)/ (2 * 3) = 3/6 + 2/6 = 5/6
|
||||
|
||||
|
||||
|
||||
### <a href="#subtraction" name="subtraction"></a>Subtraction {#subtraction}
|
||||
|
||||
|
@ -52,27 +54,27 @@ Works the same as addition, except the second fraction is subtracted (taken away
|
|||
To multiply two fractions, just multiply the numerators by each other, and the denominators by each other.
|
||||
|
||||
2/3 * 1/2 = 2/6
|
||||
|
||||
|
||||
|
||||
### <a href="#division" name="division"></a>Division {#division}
|
||||
|
||||
Treated similar to multiplication since dividing a number is the same thing as multiplying by it’s [reciprocal](https://www.mathsisfun.com/reciprocal.html).
|
||||
|
||||
1 / (1 / 2) = 1 * 2 = 2
|
||||
|
||||
|
||||
|
||||
### <a href="#simplification" name="simplification"></a>Simplification {#simplification}
|
||||
|
||||
Sometimes with the operations above, it’ll produce fractions in an unsimplified form. To avoid any confusion, I created a simplify function. It was challanging trying to figure out a way to code this. While I was browsing around for an implementation, I knocked into Euclider’s algorithm for finding the greatest common factor. Straight from the [Wikipedia article](https://en.wikipedia.org/wiki/Euclidean_algorithm) (where a is greater than b):
|
||||
|
||||
|
||||
|
||||
function gcd(a, b)
|
||||
while b ≠ 0
|
||||
t := b;
|
||||
b := a mod b;
|
||||
a := t;
|
||||
return a;
|
||||
|
||||
|
||||
|
||||
I can then simplify the fraction by dividing the numerator and denominator by the greatest common factor.
|
||||
|
||||
|
|
|
@ -5,6 +5,11 @@ date: 2015-11-30T00:34:15+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=449
|
||||
aliases:
|
||||
- /2015/11/limiting-cache-service-workers-revisited/
|
||||
- /2015/11/limiting-cache-service-workers-revisited1/
|
||||
- /2015/11/limiting-cache-service-workers-revisited2/
|
||||
- /2015/11/limiting-cache-service-workers-revisited3/
|
||||
permalink: /2015/11/limiting-cache-service-workers-revisited3/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -27,7 +32,7 @@ Summary: I rewrote how cache limiting works to address a few problems listed lat
|
|||
|
||||
I wrote a function in my [previous service worker post](https://brandonrozek.com/2015/11/service-workers/) to help limit the cache. Here’s a reminder of what it looked like.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var limitCache = function(cache, maxItems) {
|
||||
cache.keys().then(function(items) {
|
||||
if (items.length > maxItems) {
|
||||
|
@ -35,7 +40,7 @@ var limitCache = function(cache, maxItems) {
|
|||
}
|
||||
})
|
||||
}
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
### The Problem
|
||||
|
||||
|
@ -45,7 +50,7 @@ Jeremy Keith updated the service worker on his site and noticed that the images
|
|||
|
||||
Jeremy wrote a function to help trim the cache and asked when it would be appropriate to apply it.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var trimCache = function (cacheName, maxItems) {
|
||||
caches.open(cacheName)
|
||||
.then(function (cache) {
|
||||
|
@ -58,11 +63,11 @@ var trimCache = function (cacheName, maxItems) {
|
|||
});
|
||||
});
|
||||
};
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
And that got me thinking. In what situations is this problem more likely to occur? This particular problem happens when a lot of files are being called asynchronously. This problem doesn’t occur when only one file is being loaded. So when do we load a bunch of files? During page load. During page load, the browser might request css, javascript, images, etc. Which for most [websites](http://royal.pingdom.com/2011/11/21/web-pages-getting-bloated-here-is-why/), is a lot of files. Let’s now move our focus back to the humble script.js. Before, the only role it played with service workers was registering the script. However, if we can get the script to notify the service worker when the page is done loading, then the service worker will know when to trim the cache.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('https://yourwebsite.com/serviceworker.js', {scope: '/'});
|
||||
}
|
||||
|
@ -71,21 +76,21 @@ window.addEventListener("load", function() {
|
|||
navigator.serviceWorker.controller.postMessage({"command":"trimCache"});
|
||||
}
|
||||
});
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
Why <code class="language-javascript">if (navigator.serviceWorker.controller != null)</code>? Service Workers don’t take control of the page immediately but on subsequent page loads, Jake Archibald [explains](https://jakearchibald.com/2014/using-serviceworker-today/). When the service worker does have control of the page however, we can use the [postMessage api](https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage) to send a message to the service worker. Inside, I provided a json with a “command” to “trimCache”. Since we send the json to the service worker, we need to make sure that it can receive it.
|
||||
Why `if (navigator.serviceWorker.controller != null)` Service Workers don’t take control of the page immediately but on subsequent page loads, Jake Archibald [explains](https://jakearchibald.com/2014/using-serviceworker-today/). When the service worker does have control of the page however, we can use the [postMessage api](https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage) to send a message to the service worker. Inside, I provided a json with a “command” to “trimCache”. Since we send the json to the service worker, we need to make sure that it can receive it.
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
self.addEventListener("message", function(event) {
|
||||
var data = event.data;
|
||||
|
||||
|
||||
if (data.command == "trimCache") {
|
||||
trimCache(version + "pages", 25);
|
||||
trimCache(version + "images", 10);
|
||||
trimCache(version + "assets", 30);
|
||||
}
|
||||
});
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
Once it receives the command, it goes on to trim all of the caches.
|
||||
|
||||
|
@ -93,7 +98,7 @@ Once it receives the command, it goes on to trim all of the caches.
|
|||
|
||||
So whenever you download a bunch of files, make sure to run <code class="language-javascript">navigator.serviceWorker.controller.postMessage({"command":"trimCache"});</code> on the main javascript file to trim the cache. A downside to this method is that since Service Workers don’t take control during the first page load, the cache isn’t trimmed until the second page load. If you can find a way to make it so that this event happens in the first page load [tell me](mailto:hello@brandonrozek.com) about it/write a blog post. 🙂 **Update:** To get the service worker to take control of the page immediately call [self.skipWaiting()](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/skipWaiting) after the install event and [self.clients.claim()](https://developer.mozilla.org/en-US/docs/Web/API/Clients/claim) after the activate event. Current code for our humble service worker:
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
var version = 'v2.0.24:';
|
||||
|
||||
var offlineFundamentals = [
|
||||
|
@ -191,10 +196,10 @@ self.addEventListener("fetch", function(event) {
|
|||
cache.put(event.request, cacheCopy);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
//Fetch from network failed
|
||||
var fallback = function() {
|
||||
if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
|
||||
|
@ -213,10 +218,10 @@ self.addEventListener("fetch", function(event) {
|
|||
|
||||
//For HTML requests, look for file in network, then cache if network fails.
|
||||
if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
|
||||
event.respondWith(fetch(event.request).then(fetchFromNetwork, fallback));
|
||||
event.respondWith(fetch(event.request).then(fetchFromNetwork, fallback));
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//For non-HTML requests, look for file in cache, then network if no cache exists.
|
||||
event.respondWith(
|
||||
caches.match(event.request).then(function(cached) {
|
||||
|
@ -233,9 +238,9 @@ self.addEventListener("activate", function(event) {
|
|||
})
|
||||
);
|
||||
});
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
<pre><code class="language-javascript">
|
||||
```javascript
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('https://brandonrozek.com/serviceworker.js', {scope: '/'});
|
||||
}
|
||||
|
@ -244,4 +249,4 @@ window.addEventListener("load", function() {
|
|||
navigator.serviceWorker.controller.postMessage({"command":"trimCache"});
|
||||
}
|
||||
});
|
||||
</code></pre>
|
||||
```
|
|
@ -5,6 +5,8 @@ date: 2015-12-22T15:13:44+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=572
|
||||
aliases:
|
||||
- /2015/12/playing-with-qr-codes/
|
||||
permalink: /2015/12/playing-with-qr-codes/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -35,7 +37,7 @@ QR Codes aren’t prevalent in the United States of America. In fact, they&#
|
|||
|
||||
<div id="attachment_573" style="width: 235px" class="wp-caption aligncenter">
|
||||
<img aria-describedby="caption-attachment-573" class="size-medium wp-image-573" src="https://brandonrozek.com/wp-content/uploads/2016/10/heinz-2-768x1024.jpg" alt="Picture of Heinz ketchup bottle with QR Code." width="225" height="300" />
|
||||
|
||||
|
||||
<p id="caption-attachment-573" class="wp-caption-text">
|
||||
Picture by <a href="http://azadzahoory.com/2014/07/03/when-the-product-becomes-an-ad/">Azad Zahoory</a>
|
||||
</p>
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2015-12-27T15:17:12+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=599
|
||||
aliases:
|
||||
- /2015/12/creating-vcards-from-h-cards/
|
||||
permalink: /2015/12/creating-vcards-from-h-cards/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -143,7 +145,7 @@ var makeVCard = function(hCard) {
|
|||
vCard += "FN: " + name[i] + "n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Add photo
|
||||
var photo = hCard.items[0].properties.photo;
|
||||
if (typeof(photo) == "object") {
|
||||
|
@ -152,7 +154,7 @@ var makeVCard = function(hCard) {
|
|||
vCard += "PHOTO: " + photo[i] + "n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Add phone number
|
||||
var tel = hCard.items[0].properties.tel;
|
||||
if (typeof(tel) == "object") {
|
||||
|
@ -169,7 +171,7 @@ var makeVCard = function(hCard) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Add URLs
|
||||
var url = hCard.items[0].properties.url;
|
||||
if (typeof(url) == "object") {
|
||||
|
@ -178,7 +180,7 @@ var makeVCard = function(hCard) {
|
|||
vCard += "URL: " + url[i] + "n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var impp = hCard.items[0].properties.impp;
|
||||
//Add IMPP (Instant Messaging and Presence Protocol)
|
||||
if (typeof(impp) == "object") {
|
||||
|
@ -187,7 +189,7 @@ var makeVCard = function(hCard) {
|
|||
vCard += "IMPP;PREF=" + (i + 1) + ": " + impp[i] + "n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Add emails
|
||||
var email = hCard.items[0].properties.email;
|
||||
if (typeof(email) == "object") {
|
||||
|
@ -200,7 +202,7 @@ var makeVCard = function(hCard) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Add roles
|
||||
var role = hCard.items[0].properties.role;
|
||||
if (typeof(role) == "object") {
|
||||
|
@ -209,7 +211,7 @@ var makeVCard = function(hCard) {
|
|||
vCard += "ROLE: " + role[i] + "n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Add Organizations
|
||||
var org = hCard.items[0].properties.org;
|
||||
if (typeof(org) == "object") {
|
||||
|
@ -218,13 +220,13 @@ var makeVCard = function(hCard) {
|
|||
vCard += "ORG: " + org[i] + "n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Add Categories
|
||||
var category = hCard.items[0].properties.category;
|
||||
if (typeof(category) == "object") {
|
||||
vCard += "CATEGORIES: " + category.removeEmptyStrings().join(",") + "n";
|
||||
}
|
||||
|
||||
|
||||
//Add notes
|
||||
var note = hCard.items[0].properties.note;
|
||||
if (typeof(note) == "object") {
|
||||
|
@ -233,9 +235,9 @@ var makeVCard = function(hCard) {
|
|||
vCard += "NOTE: " + note[i] + "n";
|
||||
}
|
||||
}
|
||||
|
||||
return vCard + "END:VCARD";
|
||||
|
||||
return vCard + "END:VCARD";
|
||||
|
||||
}
|
||||
|
||||
Array.prototype.removeEmptyStrings = function() {
|
||||
|
@ -302,7 +304,7 @@ var render = function() {
|
|||
border: medium none;
|
||||
}
|
||||
";
|
||||
|
||||
|
||||
node.innerHTML = link + style;
|
||||
document.body.appendChild(node);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2016-08-16T23:37:09+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: http://brandonrozek.com/?p=919
|
||||
aliases:
|
||||
- /2016/08/pass-password-manager/
|
||||
permalink: /2016/08/pass-password-manager/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";N;s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:4:"none";s:3:"url";N;}'
|
||||
|
|
|
@ -5,6 +5,8 @@ date: 2017-03-07T04:29:50+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2090
|
||||
aliases:
|
||||
- /2017/03/knit-document-rstudio/
|
||||
permalink: /2017/03/knit-document-rstudio/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
|
|
@ -1,132 +1,142 @@
|
|||
---
|
||||
id: 2095
|
||||
title: Uniformity of Math.random()
|
||||
date: 2017-03-07T21:50:52+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2095
|
||||
permalink: /2017/03/uniformity-math-random/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:4:"none";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "158123669889"
|
||||
format: aside
|
||||
kind:
|
||||
- note
|
||||
---
|
||||
There are many cases where websites use random number generators to influence some sort of page behavior. One test to ensure the quality of a random number generator is to see if after many cases, the numbers produced follow a uniform distribution.
|
||||
|
||||
<!--more-->
|
||||
|
||||
Today, I will compare Internet Explorer 11, Chrome, and Firefox on a Windows 7 machine and report my results.
|
||||
|
||||
## Hypothesis
|
||||
|
||||
H0: The random numbers outputted follow the uniform distribution
|
||||
|
||||
HA: The random numbers outputted do not follow the uniform distribution
|
||||
|
||||
## Gathering Data
|
||||
|
||||
I wrote a small [website](http://share.zeropointshift.com/files/2017/03/random.html) and obtained my data by getting the CSV outputted when I use IE11, Firefox, and Chrome.
|
||||
|
||||
The website works by producing a random number using <code class='language-javascript'>Math.random()</code> between 1 and 1000 inclusive and calls the function 1,000,000 times. Storing it’s results in a file
|
||||
|
||||
This website produces a file with all the numbers separated by a comma. We want these commas to be replaced by newlines. To do so, we can run a simple command in the terminal
|
||||
|
||||
<pre class='language-bash'><code class='language-bash'>
|
||||
---
|
||||
id: 2095
|
||||
title: Uniformity of Math.random()
|
||||
date: 2017-03-07T21:50:52+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2095
|
||||
aliases:
|
||||
- /2017/03/uniformity-math-random/
|
||||
permalink: /2017/03/uniformity-math-random/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:4:"none";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "158123669889"
|
||||
format: aside
|
||||
kind:
|
||||
- note
|
||||
---
|
||||
There are many cases where websites use random number generators to influence some sort of page behavior. One test to ensure the quality of a random number generator is to see if after many cases, the numbers produced follow a uniform distribution.
|
||||
|
||||
<!--more-->
|
||||
|
||||
Today, I will compare Internet Explorer 11, Chrome, and Firefox on a Windows 7 machine and report my results.
|
||||
|
||||
## Hypothesis
|
||||
|
||||
H0: The random numbers outputted follow the uniform distribution
|
||||
|
||||
HA: The random numbers outputted do not follow the uniform distribution
|
||||
|
||||
## Gathering Data
|
||||
|
||||
I wrote a small [website](http://share.zeropointshift.com/files/2017/03/random.html) and obtained my data by getting the CSV outputted when I use IE11, Firefox, and Chrome.
|
||||
|
||||
The website works by producing a random number using <code class='language-javascript'>Math.random()</code> between 1 and 1000 inclusive and calls the function 1,000,000 times. Storing it’s results in a file
|
||||
|
||||
This website produces a file with all the numbers separated by a comma. We want these commas to be replaced by newlines. To do so, we can run a simple command in the terminal
|
||||
|
||||
```bash
|
||||
grep -oE '[0-9]+' Random.csv > Random_corrected.csv
|
||||
</code></pre>
|
||||
|
||||
Do this with all three files and make sure to keep track of which is which.
|
||||
|
||||
Here are a copy of my files for [Firefox](https://brandonrozek.com/wp-content/uploads/2017/03/Firefox_corrected.csv), [Chrome](https://brandonrozek.com/wp-content/uploads/2017/03/Chrome_corrected-1.csv), and [IE11](https://brandonrozek.com/wp-content/uploads/2017/03/IE11_corrected.csv)
|
||||
|
||||
## Check Conditions
|
||||
|
||||
Since we’re interested in if the random values occur uniformly, we need to perform a Chi-Square test for Goodness of Fit. With every test comes some assumptions
|
||||
|
||||
<u>Counted Data Condition:</u> The data can be converted from quantatative to count data.
|
||||
|
||||
<u>Independence Assumption:</u> One random value does not affect another.
|
||||
|
||||
<u>Expected Cell Frequency Condition:</u> The expected counts are going to be 10000
|
||||
|
||||
Since all of the conditions are met, we can use the Chi-square test of Goodness of Fit
|
||||
|
||||
## Descriptive Statistics
|
||||
|
||||
For the rest of the article, we will use R for analysis. Looking at the histograms for the three browsers below. The random numbers all appear to occur uniformly
|
||||
|
||||
<pre class="language-R"><code class='language-R'>rm(list=ls())
|
||||
```
|
||||
|
||||
Do this with all three files and make sure to keep track of which is which.
|
||||
|
||||
Here are a copy of my files for [Firefox](https://brandonrozek.com/wp-content/uploads/2017/03/Firefox_corrected.csv), [Chrome](https://brandonrozek.com/wp-content/uploads/2017/03/Chrome_corrected-1.csv), and [IE11](https://brandonrozek.com/wp-content/uploads/2017/03/IE11_corrected.csv)
|
||||
|
||||
## Check Conditions
|
||||
|
||||
Since we’re interested in if the random values occur uniformly, we need to perform a Chi-Square test for Goodness of Fit. With every test comes some assumptions
|
||||
|
||||
<u>Counted Data Condition:</u> The data can be converted from quantatative to count data.
|
||||
|
||||
<u>Independence Assumption:</u> One random value does not affect another.
|
||||
|
||||
<u>Expected Cell Frequency Condition:</u> The expected counts are going to be 10000
|
||||
|
||||
Since all of the conditions are met, we can use the Chi-square test of Goodness of Fit
|
||||
|
||||
## Descriptive Statistics
|
||||
|
||||
For the rest of the article, we will use R for analysis. Looking at the histograms for the three browsers below. The random numbers all appear to occur uniformly
|
||||
|
||||
```R
|
||||
rm(list=ls())
|
||||
chrome = read.csv("~/Chrome_corrected.csv", header = F)
|
||||
firefox = read.csv("~/Firefox_corrected.csv", header = F)
|
||||
ie11 = read.csv("~/IE11_corrected.csv", header = F)
|
||||
</code></pre>
|
||||
|
||||
<pre class="language-R"><code class='language-R'>
|
||||
hist(ie11$V1, main = "Distribution of Random Values for IE11", xlab = "Random Value")</code></pre>
|
||||
|
||||
![](https://brandonrozek.com/wp-content/uploads/2017/03/ie11hist.png)
|
||||
|
||||
<pre class="language-R"><code class='language-R'>hist(firefox$V1, main = "Distribution of Random Values for Firefox", xlab = "Random Value")</code></pre>
|
||||
|
||||
![](https://brandonrozek.com/wp-content/uploads/2017/03/firefoxhist.png)
|
||||
|
||||
<pre class="language-R"><code class='language-R'>hist(chrome$V1, main = "Distribution of Random Values for Chrome", xlab = "Random Value")</code></pre>
|
||||
|
||||
![](https://brandonrozek.com/wp-content/uploads/2017/03/chromehist.png)
|
||||
|
||||
## Chi-Square Test
|
||||
|
||||
Before we run our test, we need to convert the quantatative data to count data by using the plyr package
|
||||
|
||||
<pre class="language-R"><code class='language-R'>#Transform to count data
|
||||
```
|
||||
|
||||
```R
|
||||
hist(ie11$V1, main = "Distribution of Random Values for IE11", xlab = "Random Value")
|
||||
```
|
||||
|
||||
![](https://brandonrozek.com/wp-content/uploads/2017/03/ie11hist.png)
|
||||
|
||||
```R
|
||||
hist(firefox$V1, main = "Distribution of Random Values for Firefox", xlab = "Random Value")
|
||||
```
|
||||
|
||||
![](https://brandonrozek.com/wp-content/uploads/2017/03/firefoxhist.png)
|
||||
|
||||
```R
|
||||
hist(chrome$V1, main = "Distribution of Random Values for Chrome", xlab = "Random Value")
|
||||
```
|
||||
|
||||
![](https://brandonrozek.com/wp-content/uploads/2017/03/chromehist.png)
|
||||
|
||||
## Chi-Square Test
|
||||
|
||||
Before we run our test, we need to convert the quantatative data to count data by using the plyr package
|
||||
|
||||
```R
|
||||
#Transform to count data
|
||||
library(plyr)
|
||||
chrome_count = count(chrome)
|
||||
firefox_count = count(firefox)
|
||||
ie11_count = count(ie11)
|
||||
</code></pre>
|
||||
|
||||
Run the tests
|
||||
|
||||
<pre class='language-R'><code class='language-R'>
|
||||
```
|
||||
|
||||
Run the tests
|
||||
|
||||
```R
|
||||
# Chi-Square Test for Goodness-of-Fit
|
||||
chrome_test = chisq.test(chrome_count$freq)
|
||||
firefox_test = chisq.test(firefox_count$freq)
|
||||
ie11_test = chisq.test(ie11_count$freq)
|
||||
|
||||
# Test results
|
||||
chrome_test</code></pre>
|
||||
|
||||
As you can see in the test results below, we fail to reject the null hypothesis at a 5% significance level because all of the p-values are above 0.05.
|
||||
|
||||
chrome_test
|
||||
```
|
||||
|
||||
As you can see in the test results below, we fail to reject the null hypothesis at a 5% significance level because all of the p-values are above 0.05.
|
||||
|
||||
##
|
||||
## Chi-squared test for given probabilities
|
||||
##
|
||||
## data: chrome_count$freq
|
||||
## X-squared = 101.67, df = 99, p-value = 0.4069
|
||||
|
||||
<pre class="r"><code>firefox_test</code></pre>
|
||||
|
||||
## X-squared = 101.67, df = 99, p-value = 0.4069
|
||||
|
||||
`firefox_test`
|
||||
|
||||
##
|
||||
## Chi-squared test for given probabilities
|
||||
##
|
||||
## data: firefox_count$freq
|
||||
## X-squared = 105.15, df = 99, p-value = 0.3172
|
||||
|
||||
<pre class="r"><code>ie11_test</code></pre>
|
||||
|
||||
## X-squared = 105.15, df = 99, p-value = 0.3172
|
||||
|
||||
`ie11_test`
|
||||
|
||||
##
|
||||
## Chi-squared test for given probabilities
|
||||
##
|
||||
## data: ie11_count$freq
|
||||
## X-squared = 78.285, df = 99, p-value = 0.9384
|
||||
|
||||
## Conclusion
|
||||
|
||||
At a 5% significance level, we fail to obtain enough evidence to suggest that the distribution of random number is not uniform. This is a good thing since it shows us that our random number generators give all numbers an equal chance of being represented. We can use <code class='language-javascript'>Math.random()</code> with ease of mind.
|
||||
## X-squared = 78.285, df = 99, p-value = 0.9384
|
||||
|
||||
## Conclusion
|
||||
|
||||
At a 5% significance level, we fail to obtain enough evidence to suggest that the distribution of random number is not uniform. This is a good thing since it shows us that our random number generators give all numbers an equal chance of being represented. We can use `Math.random()` with ease of mind.
|
|
@ -1,66 +1,68 @@
|
|||
---
|
||||
id: 2115
|
||||
title: Simplifying Expressions with Octave
|
||||
date: 2017-03-09T02:09:58+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2115
|
||||
permalink: /2017/03/simplifying-expressions-octave/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:22:"bridgy-publish_twitter";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "158172999969"
|
||||
mf2_syndication:
|
||||
- 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/839659534146801665";}'
|
||||
format: aside
|
||||
kind:
|
||||
- note
|
||||
---
|
||||
Octave is a high level programming language intended for numerical computations. One of the cool features of this is that with symbolic expressions, you can then simplify mathematical expressions.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## Setup
|
||||
|
||||
First install [Octave](https://www.gnu.org/software/octave/) and the [symbolic package](https://octave.sourceforge.io/symbolic/) using the website or your package manager of choice.
|
||||
|
||||
Then in octave type in the following code
|
||||
|
||||
```MATLAB
|
||||
pkg load symbolic
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
For every variable not defined earlier in your expression, make sure to declare it as a symbolic data type
|
||||
|
||||
```MATLAB
|
||||
syms x y
|
||||
```
|
||||
|
||||
Then make an expression
|
||||
|
||||
```MATLAB
|
||||
expr = y + sin(x)^2 + cos(x)^2
|
||||
```
|
||||
|
||||
You can then ask Octave to simplify the expression for you
|
||||
|
||||
```MATLAB
|
||||
---
|
||||
id: 2115
|
||||
title: Simplifying Expressions with Octave
|
||||
date: 2017-03-09T02:09:58+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2115
|
||||
aliases:
|
||||
- /2017/03/simplifying-expressions-octave/
|
||||
permalink: /2017/03/simplifying-expressions-octave/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:22:"bridgy-publish_twitter";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "158172999969"
|
||||
mf2_syndication:
|
||||
- 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/839659534146801665";}'
|
||||
format: aside
|
||||
kind:
|
||||
- note
|
||||
---
|
||||
Octave is a high level programming language intended for numerical computations. One of the cool features of this is that with symbolic expressions, you can then simplify mathematical expressions.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## Setup
|
||||
|
||||
First install [Octave](https://www.gnu.org/software/octave/) and the [symbolic package](https://octave.sourceforge.io/symbolic/) using the website or your package manager of choice.
|
||||
|
||||
Then in octave type in the following code
|
||||
|
||||
```MATLAB
|
||||
pkg load symbolic
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
For every variable not defined earlier in your expression, make sure to declare it as a symbolic data type
|
||||
|
||||
```MATLAB
|
||||
syms x y
|
||||
```
|
||||
|
||||
Then make an expression
|
||||
|
||||
```MATLAB
|
||||
expr = y + sin(x)^2 + cos(x)^2
|
||||
```
|
||||
|
||||
You can then ask Octave to simplify the expression for you
|
||||
|
||||
```MATLAB
|
||||
simp_expr = simplify(expr)
|
||||
```
|
||||
|
||||
Displaying it shows it as
|
||||
|
||||
```MATLAB
|
||||
(sym) y + 1
|
||||
```
|
||||
|
||||
Which is indeed a simplification using a trig identity 🙂
|
||||
|
||||
Update: Octave's symbolic is based on [SymPy](https://www.sympy.org/en/index.html). If you're confortable with Python, I recommend checking it out.
|
||||
```
|
||||
|
||||
Displaying it shows it as
|
||||
|
||||
```MATLAB
|
||||
(sym) y + 1
|
||||
```
|
||||
|
||||
Which is indeed a simplification using a trig identity 🙂
|
||||
|
||||
Update: Octave's symbolic is based on [SymPy](https://www.sympy.org/en/index.html). If you're confortable with Python, I recommend checking it out.
|
||||
|
|
|
@ -1,80 +1,83 @@
|
|||
---
|
||||
id: 2089
|
||||
title: Monte Carlo Pi
|
||||
date: 2017-03-14T05:31:21+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2089
|
||||
permalink: /2017/03/monte-carlo-pi/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
tumblr_post_id:
|
||||
- "158383170019"
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:22:"bridgy-publish_twitter";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
mf2_syndication:
|
||||
- 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/841522141346570244";}'
|
||||
format: aside
|
||||
kind:
|
||||
- note
|
||||
---
|
||||
Using Monte Carlo methods, we can create a simulation that approximates pi. In this post, we will go over the math behind the approximation and the code.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## The Math
|
||||
|
||||
Pi is a mathematical constant consisting of the ratio between the circumfrence of a circle and it’s diameter.
|
||||
|
||||
The circumfrence of the circle is defined to be $$ C = 2\pi r$$ while the diameter of the circle is $$d = 2r$$
|
||||
|
||||
Take the ratio between the two and you get $$\frac{2\pi r}{2r} = \pi$$
|
||||
|
||||
Now let us consider the area of a circle. One can derive the area of a circle by taking the integral of the circumfrence with respect to it’s radius $$ A_{circle} = \int{(2\pi r) dr} = \pi r^2 $$
|
||||
|
||||
Let us simplify the formula more by setting the radius equal to one. $$A_{circle} = \pi$$
|
||||
|
||||
Now consider only the first quadrant of the circle. Since our circle is centered at the origin and all the points on the circumfrence is equidistant from the center, our area is now $$A_{circle} = \frac{1}{4} \pi$$
|
||||
|
||||
And bound the quarter-circle in a 1×1 box with an area of $$A_{square} = 1^2 = 1$$
|
||||
|
||||
Notice that the ratio between the circle and the square is a quarter of pi $$\frac{A\_{circle}}{A\_{square}} = \frac{\frac{1}{4} \pi}{1} = \frac{1}{4} \pi$$
|
||||
|
||||
## Simulation and Statisitcs
|
||||
|
||||
The formula for a circle centered at the origin with radius one is $$x^2 + y^2 = 1$$
|
||||
|
||||
Let us focus again on the first quadrent, and do a Monte Carlo simulation to find the area of the quarter-circle
|
||||
|
||||
![](https://brandonrozek.com/wp-content/uploads/2017/03/circlefilled.png)
|
||||
|
||||
We can do this by what is called the dart board method. We generate a random x and y between 0 and 1. If it satisfies the inequality $$x^2 + y^2 \leq 1$$ then it counts as being inside the circle, if not then it lies outside the circle.
|
||||
|
||||
That point will count as an really small area. The point will always be inside the square but may sometimes be inside the circle. Running the simulations a large number of times allows us to add up all the tiny little areas that make up the circle and the square.
|
||||
|
||||
To add up these small areas we need to make an assumption. The assumption is that the variance of all the little Monte Carlo trials are the same. Since we are using a psuedo-random number generator, it is safe to assume it is met.
|
||||
|
||||
This will allow us to perform a pooled empiricle probability on the simulations to sum up the areas.
|
||||
|
||||
Meaning the area of the circle will be the number of times that the inequality was satisfied $$A_{circle} = \# Successes$$
|
||||
|
||||
And the area of the square will be the number of times the simulation was run, since the random numbers generated will always be between 0 and 1 $$A_{square} = \# Trials$$
|
||||
|
||||
Recall that taking the ratio of the area of the circle and the area of the square is a fourth of pi. $$\frac{\frac{1}{4} \pi}{1} = \frac{1}{4} \pi$$
|
||||
|
||||
Multiply this number by 4 and you get the value for pi.
|
||||
|
||||
This tells us that four times the probability that the randomly generated point is in the circle is equal to pi.
|
||||
|
||||
$$\pi = 4 \* (Probability\ of\ being\ inside\ circle) = 4 \* \frac{\# Success}{\# Trials} = 4 * \frac{A\_{circle}}{A\_{square}}$$
|
||||
|
||||
## Implementation
|
||||
|
||||
For the Monte Carlo simulation I used Java. The BigDecimal implementation was used so that there wouldn’t be any issue with integer size limits
|
||||
|
||||
<pre class='language-java'><code class='language-java'>/** Calculates Pi
|
||||
---
|
||||
id: 2089
|
||||
title: Monte Carlo Pi
|
||||
date: 2017-03-14T05:31:21+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2089
|
||||
aliases:
|
||||
- /2017/03/monte-carlo-pi/
|
||||
permalink: /2017/03/monte-carlo-pi/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
tumblr_post_id:
|
||||
- "158383170019"
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:22:"bridgy-publish_twitter";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
mf2_syndication:
|
||||
- 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/841522141346570244";}'
|
||||
format: aside
|
||||
kind:
|
||||
- note
|
||||
---
|
||||
Using Monte Carlo methods, we can create a simulation that approximates pi. In this post, we will go over the math behind the approximation and the code.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## The Math
|
||||
|
||||
Pi is a mathematical constant consisting of the ratio between the circumfrence of a circle and it’s diameter.
|
||||
|
||||
The circumfrence of the circle is defined to be $$ C = 2\pi r$$ while the diameter of the circle is $$d = 2r$$
|
||||
|
||||
Take the ratio between the two and you get $$\frac{2\pi r}{2r} = \pi$$
|
||||
|
||||
Now let us consider the area of a circle. One can derive the area of a circle by taking the integral of the circumfrence with respect to it’s radius $$ A_{circle} = \int{(2\pi r) dr} = \pi r^2 $$
|
||||
|
||||
Let us simplify the formula more by setting the radius equal to one. $$A_{circle} = \pi$$
|
||||
|
||||
Now consider only the first quadrant of the circle. Since our circle is centered at the origin and all the points on the circumfrence is equidistant from the center, our area is now $$A_{circle} = \frac{1}{4} \pi$$
|
||||
|
||||
And bound the quarter-circle in a 1×1 box with an area of $$A_{square} = 1^2 = 1$$
|
||||
|
||||
Notice that the ratio between the circle and the square is a quarter of pi $$\frac{A\_{circle}}{A\_{square}} = \frac{\frac{1}{4} \pi}{1} = \frac{1}{4} \pi$$
|
||||
|
||||
## Simulation and Statisitcs
|
||||
|
||||
The formula for a circle centered at the origin with radius one is $$x^2 + y^2 = 1$$
|
||||
|
||||
Let us focus again on the first quadrent, and do a Monte Carlo simulation to find the area of the quarter-circle
|
||||
|
||||
![](https://brandonrozek.com/wp-content/uploads/2017/03/circlefilled.png)
|
||||
|
||||
We can do this by what is called the dart board method. We generate a random x and y between 0 and 1. If it satisfies the inequality $$x^2 + y^2 \leq 1$$ then it counts as being inside the circle, if not then it lies outside the circle.
|
||||
|
||||
That point will count as an really small area. The point will always be inside the square but may sometimes be inside the circle. Running the simulations a large number of times allows us to add up all the tiny little areas that make up the circle and the square.
|
||||
|
||||
To add up these small areas we need to make an assumption. The assumption is that the variance of all the little Monte Carlo trials are the same. Since we are using a psuedo-random number generator, it is safe to assume it is met.
|
||||
|
||||
This will allow us to perform a pooled empiricle probability on the simulations to sum up the areas.
|
||||
|
||||
Meaning the area of the circle will be the number of times that the inequality was satisfied $$A_{circle} = \# Successes$$
|
||||
|
||||
And the area of the square will be the number of times the simulation was run, since the random numbers generated will always be between 0 and 1 $A_{square} = \# Trials$
|
||||
|
||||
Recall that taking the ratio of the area of the circle and the area of the square is a fourth of pi. $$\frac{\frac{1}{4} \pi}{1} = \frac{1}{4} \pi$$
|
||||
|
||||
Multiply this number by 4 and you get the value for pi.
|
||||
|
||||
This tells us that four times the probability that the randomly generated point is in the circle is equal to pi.
|
||||
|
||||
$$\pi = 4 * (Probability\ of\ being\ inside\ circle) = 4 * \frac{\# Success}{\# Trials} = 4 * \frac{A\_{circle}}{A\_{square}}$$
|
||||
|
||||
## Implementation
|
||||
|
||||
For the Monte Carlo simulation I used Java. The BigDecimal implementation was used so that there wouldn’t be any issue with integer size limits
|
||||
|
||||
```java
|
||||
/** Calculates Pi
|
||||
* @author Brandon Rozek
|
||||
*/
|
||||
// Big Integers are used so we don't run into the integer size limit
|
||||
|
@ -85,10 +88,10 @@ class MonteCarloPi {
|
|||
|
||||
BigInteger successes = BigInteger.ZERO;
|
||||
BigInteger trials = BigInteger.ZERO;
|
||||
</code></pre>
|
||||
|
||||
For this simulation, we will run 1,000,000,000 trials
|
||||
|
||||
</code></pre>
|
||||
|
||||
For this simulation, we will run 1,000,000,000 trials
|
||||
|
||||
<pre class='language-java'><code class='language-java'> BigInteger numTrials = new BigInteger("1000000000");
|
||||
/*
|
||||
Monte Carlo Simulation
|
||||
|
@ -104,22 +107,23 @@ for (; trials.compareTo(numTrials) < 0; trials = trials.add(BigInteger.ONE))
|
|||
successes = successes.add(BigInteger.ONE);
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
And then we finalize it with a quick calculation of pi
|
||||
|
||||
<pre class='language=java'><code class='language-java'>// (Number of successes) / (Number of trials) * 4 gives the approximation for pi
|
||||
```
|
||||
|
||||
And then we finalize it with a quick calculation of pi
|
||||
|
||||
```java
|
||||
// (Number of successes) / (Number of trials) * 4 gives the approximation for pi
|
||||
BigDecimal pi = new BigDecimal(successes)
|
||||
.divide(new BigDecimal(trials))
|
||||
.multiply(new BigDecimal("4"));
|
||||
System.out.println("The calculated value of pi is: " + pi);
|
||||
}}
|
||||
</code></pre>
|
||||
|
||||
## Conclusion
|
||||
|
||||
We found an approximation of pi using the Monte Carlo methods! I find that really awesome, however, there are some concerns I have with this approach.
|
||||
|
||||
1) We don’t keep track of double counting. One possible solution for this is increasing the radius and bounding box appropriately so that the probability of double counting is low.
|
||||
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
We found an approximation of pi using the Monte Carlo methods! I find that really awesome, however, there are some concerns I have with this approach.
|
||||
|
||||
1) We don’t keep track of double counting. One possible solution for this is increasing the radius and bounding box appropriately so that the probability of double counting is low.
|
||||
|
||||
2) Speed. The more trials you ask it to run, the longer it takes to perform all of the simulations. One possible way around this is to write a parrallel version of this code. That’s possible because of the equal variance that we spoke of earlier. Pooling the successses and trials will still result in a good approximation.
|
|
@ -1,40 +1,42 @@
|
|||
---
|
||||
id: 2174
|
||||
title: Viewing Java Applets
|
||||
date: 2017-05-24T15:59:45+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2174
|
||||
permalink: /2017/05/viewing-java-applets/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:22:"bridgy-publish_twitter";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "161024360884"
|
||||
mf2_syndication:
|
||||
- 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/867409810932760576";}'
|
||||
kind:
|
||||
- article
|
||||
---
|
||||
When you use an IDE there are many things you can take for granted. A section of an intro level computer science course at my university uses [JGrasp](http://www.jgrasp.org/) to build Java Applets.
|
||||
|
||||
Following around using a normal text editor, I found that I couldn’t just compile and run the code like I have with my java programs in the past. To be able to help around and assist in the course, I need to be able to build and run these applications. The rest of this article describes the process I underwent to be able to use my existing setup to write and build java applets. Of course you can always install JGrasp and have that all built in, but it’s always nice to not have to change your workflow.
|
||||
|
||||
<!--more-->
|
||||
|
||||
When I tried following along, I would receive the following error
|
||||
|
||||
Main method not found in class HelloWorld, please define main method as...
|
||||
|
||||
Which makes sense since I have never defined a main method inside my source code. So how do I go about doing this?
|
||||
|
||||
## Setup
|
||||
|
||||
Java Applets are meant to run on web pages, because of this one needs an html file to host the applet. The following code gives you the bare minimum for setting up the html file. I called it `HelloWorld.html`.
|
||||
|
||||
---
|
||||
id: 2174
|
||||
title: Viewing Java Applets
|
||||
date: 2017-05-24T15:59:45+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2174
|
||||
aliases:
|
||||
- /2017/05/viewing-java-applets/
|
||||
permalink: /2017/05/viewing-java-applets/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:22:"bridgy-publish_twitter";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "161024360884"
|
||||
mf2_syndication:
|
||||
- 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/867409810932760576";}'
|
||||
kind:
|
||||
- article
|
||||
---
|
||||
When you use an IDE there are many things you can take for granted. A section of an intro level computer science course at my university uses [JGrasp](http://www.jgrasp.org/) to build Java Applets.
|
||||
|
||||
Following around using a normal text editor, I found that I couldn’t just compile and run the code like I have with my java programs in the past. To be able to help around and assist in the course, I need to be able to build and run these applications. The rest of this article describes the process I underwent to be able to use my existing setup to write and build java applets. Of course you can always install JGrasp and have that all built in, but it’s always nice to not have to change your workflow.
|
||||
|
||||
<!--more-->
|
||||
|
||||
When I tried following along, I would receive the following error
|
||||
|
||||
Main method not found in class HelloWorld, please define main method as...
|
||||
|
||||
Which makes sense since I have never defined a main method inside my source code. So how do I go about doing this?
|
||||
|
||||
## Setup
|
||||
|
||||
Java Applets are meant to run on web pages, because of this one needs an html file to host the applet. The following code gives you the bare minimum for setting up the html file. I called it `HelloWorld.html`.
|
||||
|
||||
<pre class='language-html'><code class='language-html'>
|
||||
<html>
|
||||
<head><title>Applet Container<title>
|
||||
|
@ -42,12 +44,12 @@ Java Applets are meant to run on web pages, because of this one needs an html fi
|
|||
<applet code='HelloWorld.class' width=400 height=400></applet>
|
||||
</body>
|
||||
</html>
|
||||
</code></pre>
|
||||
|
||||
## Hello World Program
|
||||
|
||||
To get it up and running, I will show a “Hello World” like application for applets.
|
||||
|
||||
</code></pre>
|
||||
|
||||
## Hello World Program
|
||||
|
||||
To get it up and running, I will show a “Hello World” like application for applets.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
import javax.swing.JApplet;
|
||||
import java.awt.Graphics;
|
||||
|
@ -57,18 +59,18 @@ public class HelloWorld extends JApplet {
|
|||
g.drawString("Hello World", 30, 30);
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
## Running the Applet
|
||||
|
||||
Now we need to compile the code
|
||||
|
||||
<pre class='langauge-bash'><code class='language-bash'>javac HelloWorld.java</code></pre>
|
||||
|
||||
Then run the appletviewer
|
||||
|
||||
<pre class='language-bash'><code class='language-bash'>appletviewer HelloWorld.html</code></pre>
|
||||
|
||||
## Conclusion
|
||||
|
||||
</code></pre>
|
||||
|
||||
## Running the Applet
|
||||
|
||||
Now we need to compile the code
|
||||
|
||||
<pre class='langauge-bash'><code class='language-bash'>javac HelloWorld.java</code></pre>
|
||||
|
||||
Then run the appletviewer
|
||||
|
||||
<pre class='language-bash'><code class='language-bash'>appletviewer HelloWorld.html</code></pre>
|
||||
|
||||
## Conclusion
|
||||
|
||||
This tutorial concludes the setup of running a simple Java applet. From here you can look at the different methods in the [Graphics library](https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html) and play around 😀
|
|
@ -1,67 +1,69 @@
|
|||
---
|
||||
id: 2198
|
||||
title: Java Swing Components
|
||||
date: 2017-06-05T23:30:18+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2198
|
||||
permalink: /2017/06/java-swing-components/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:4:"none";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "161484582559"
|
||||
kind:
|
||||
- article
|
||||
---
|
||||
This post, over time, will serve as a reference to myself and others of the different UI components available in the Swing library. This post assumes a general familiarity with setting up a basic Swing application and focuses only on the individual components.
|
||||
|
||||
<!--more-->
|
||||
|
||||
### Buttons
|
||||
|
||||
Buttons are created using the JButton component. The constructor takes the text placed inside the button.
|
||||
|
||||
---
|
||||
id: 2198
|
||||
title: Java Swing Components
|
||||
date: 2017-06-05T23:30:18+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2198
|
||||
aliases:
|
||||
- /2017/06/java-swing-components/
|
||||
permalink: /2017/06/java-swing-components/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:4:"none";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "161484582559"
|
||||
kind:
|
||||
- article
|
||||
---
|
||||
This post, over time, will serve as a reference to myself and others of the different UI components available in the Swing library. This post assumes a general familiarity with setting up a basic Swing application and focuses only on the individual components.
|
||||
|
||||
<!--more-->
|
||||
|
||||
### Buttons
|
||||
|
||||
Buttons are created using the JButton component. The constructor takes the text placed inside the button.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
JButton stopBtn = new JButton("Stop");
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/stopbutton.png" alt="" width="67" height="25" class="alignnone size-full wp-image-2211" />
|
||||
|
||||
You can also add images inside a button. To do that you need to get the image and make it into an icon. The following code grabs the image file “smallpanda.jpg” from the current working directory.
|
||||
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/stopbutton.png" alt="" width="67" height="25" class="alignnone size-full wp-image-2211" />
|
||||
|
||||
You can also add images inside a button. To do that you need to get the image and make it into an icon. The following code grabs the image file “smallpanda.jpg” from the current working directory.
|
||||
|
||||
<pre class='langauge-java'><code class='language-java'>
|
||||
Image img = this.getImage(this.getCodeBase(), "smallpanda.jpg");
|
||||
ImageIcon imgIcon = new ImageIcon(img);
|
||||
JButton feedBtn = new JButton("Feed", imgIcon);
|
||||
</code></pre>
|
||||
|
||||
Sometimes, you want to change the location of the text in the button. Like say, we want to place the text in the center horizontally and bottom vertically.
|
||||
|
||||
</code></pre>
|
||||
|
||||
Sometimes, you want to change the location of the text in the button. Like say, we want to place the text in the center horizontally and bottom vertically.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
feedBtn.setHorizontalTextPosition(JButton.CENTER);
|
||||
feedBtn.setVerticalTextPosition(JButton.BOTTOM);
|
||||
</code></pre>
|
||||
|
||||
Don’t forget to add your buttons to the screen!
|
||||
|
||||
</code></pre>
|
||||
|
||||
Don’t forget to add your buttons to the screen!
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
this.add(stopBtn);
|
||||
this.add(feedBtn);
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/smallpandabutton.png" alt="" width="234" height="181" class="alignnone size-full wp-image-2210" />
|
||||
|
||||
### Labels and Textfields
|
||||
|
||||
One of the most common forms of input is a text field, usually distinguished with a label. Those components are called JTextField and JLabel respectively. The constructor for JTextArea can take just the width of the text field, or another common use is to have already inputed text and its width.
|
||||
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/smallpandabutton.png" alt="" width="234" height="181" class="alignnone size-full wp-image-2210" />
|
||||
|
||||
### Labels and Textfields
|
||||
|
||||
One of the most common forms of input is a text field, usually distinguished with a label. Those components are called JTextField and JLabel respectively. The constructor for JTextArea can take just the width of the text field, or another common use is to have already inputed text and its width.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
JLabel nameLabel = new JLabel("Enter in your name: ");
|
||||
|
||||
|
||||
// Create an input and set the width to be 10px wide
|
||||
JTextField nameInput = new JTextField(10);
|
||||
//Override nameInput with a field already contains the text "Brandon"
|
||||
|
@ -70,14 +72,14 @@ One of the most common forms of input is a text field, usually distinguished wit
|
|||
|
||||
this.add(nameLabel);
|
||||
this.add(nameInput);
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/labeltextfield.png" alt="" width="274" height="24" class="alignnone size-full wp-image-2209" />
|
||||
|
||||
### Checkboxes
|
||||
|
||||
Checkboxes are commonly used when giving the possibility for multiple answers. Such as, check all of the foods that you like.
|
||||
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/labeltextfield.png" alt="" width="274" height="24" class="alignnone size-full wp-image-2209" />
|
||||
|
||||
### Checkboxes
|
||||
|
||||
Checkboxes are commonly used when giving the possibility for multiple answers. Such as, check all of the foods that you like.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
JCheckBox pizza = new JCheckBox("Pizza");
|
||||
JCheckBox noodles = new JCheckBox("Noodles");
|
||||
|
@ -85,12 +87,12 @@ Checkboxes are commonly used when giving the possibility for multiple answers. S
|
|||
this.add(pizza);
|
||||
this.add(noodles);
|
||||
this.add(rice);
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/checkboxes.png" alt="" width="206" height="40" class="alignnone size-full wp-image-2207" />
|
||||
|
||||
You can even replace the default look of the checkbox with an image. To do this, you need to make image icons for both when it’s checked and when it’s unchecked.
|
||||
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/checkboxes.png" alt="" width="206" height="40" class="alignnone size-full wp-image-2207" />
|
||||
|
||||
You can even replace the default look of the checkbox with an image. To do this, you need to make image icons for both when it’s checked and when it’s unchecked.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
Image checkedImage = this.getImage(this.getCodeBase(), "checked.png");
|
||||
Image uncheckedImage = this.getImage(this.getCodeBase(), "unchecked.png");
|
||||
|
@ -102,31 +104,31 @@ JCheckBox checkbox = new JCheckBox("Check Me", uncheckedIcon);
|
|||
checkbox.setSelectedIcon(checkedIcon);
|
||||
|
||||
this.add(checkbox);
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/unchecked.png" alt="" width="187" height="123" class="alignnone size-full wp-image-2213" />
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/checked.png" alt="" width="186" height="102" class="alignnone size-full wp-image-2208" />
|
||||
|
||||
### Text Areas
|
||||
|
||||
Text Areas are different from text fields in which it is made to be able to hold multiple lines of text. It’s called JTextArea and its construction takes a width and height as it’s arguments.
|
||||
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/unchecked.png" alt="" width="187" height="123" class="alignnone size-full wp-image-2213" />
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/checked.png" alt="" width="186" height="102" class="alignnone size-full wp-image-2208" />
|
||||
|
||||
### Text Areas
|
||||
|
||||
Text Areas are different from text fields in which it is made to be able to hold multiple lines of text. It’s called JTextArea and its construction takes a width and height as it’s arguments.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
JTextArea textarea = new JTextArea(10, 10);
|
||||
</code></pre>
|
||||
|
||||
By default, when the someone inputs more text than the size can hold, it will automatically grow with the text inputted. To override this behaviour and instead introuduce scroll bars. One must define a ScrollPane and put the TextArea inside of it by using it as the scroll pane’s argument for its constructor.
|
||||
|
||||
</code></pre>
|
||||
|
||||
By default, when the someone inputs more text than the size can hold, it will automatically grow with the text inputted. To override this behaviour and instead introuduce scroll bars. One must define a ScrollPane and put the TextArea inside of it by using it as the scroll pane’s argument for its constructor.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
JScrollPane scrollPane = new JScrollPane(textarea);
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/textarea.png" alt="" width="119" height="149" class="alignnone size-full wp-image-2212" />
|
||||
|
||||
### Radio Buttons
|
||||
|
||||
Radio buttons are used for when you only want one out of many different options to be selected. For this, one needs to define a button group that houses the radio buttons for the user to choose from. This can be achieved with ButtonGroup and JRadioButton respectively.
|
||||
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/textarea.png" alt="" width="119" height="149" class="alignnone size-full wp-image-2212" />
|
||||
|
||||
### Radio Buttons
|
||||
|
||||
Radio buttons are used for when you only want one out of many different options to be selected. For this, one needs to define a button group that houses the radio buttons for the user to choose from. This can be achieved with ButtonGroup and JRadioButton respectively.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
// Make the radio buttons
|
||||
JRadioButton radio1 = new JRadioButton("Pies");
|
||||
|
@ -143,54 +145,54 @@ desserts.add(radio3);
|
|||
this.add(radio1);
|
||||
this.add(radio2);
|
||||
this.add(radio3);
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/radiobuttons.png" alt="" width="211" height="34" class="alignnone size-full wp-image-2218" />
|
||||
|
||||
### JList
|
||||
|
||||
To display a list of items that are clickable by the user, you can use a `JList`. JLists require a model that stores the list implementation, we’ll use `DefaultListModel` to achieve this purpose.
|
||||
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/radiobuttons.png" alt="" width="211" height="34" class="alignnone size-full wp-image-2218" />
|
||||
|
||||
### JList
|
||||
|
||||
To display a list of items that are clickable by the user, you can use a `JList`. JLists require a model that stores the list implementation, we’ll use `DefaultListModel` to achieve this purpose.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
DefaultListModel model = new DefaultListModel();
|
||||
JList list = new JList(model);
|
||||
</code></pre>
|
||||
|
||||
To add scrolling capabilities, remember to add it to a scroll pane
|
||||
|
||||
</code></pre>
|
||||
|
||||
To add scrolling capabilities, remember to add it to a scroll pane
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
JScollPane sp = new JScrollPane(list);
|
||||
</code></pre>
|
||||
|
||||
You can set the number of items you wish to see in the list. The example below, allows us to see three items in the list.
|
||||
|
||||
</code></pre>
|
||||
|
||||
You can set the number of items you wish to see in the list. The example below, allows us to see three items in the list.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
list.setVisibleRowCount(3);
|
||||
</code></pre>
|
||||
|
||||
There are a variety of ways to add items to the list. If a number is specified that tells it to place it at the index specified. Starting from the top at zero, to the button.
|
||||
|
||||
</code></pre>
|
||||
|
||||
There are a variety of ways to add items to the list. If a number is specified that tells it to place it at the index specified. Starting from the top at zero, to the button.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
model.addElement("Apples")
|
||||
model.addElement("Cherries");
|
||||
model.addElement("Bananas");
|
||||
// Adds 'Oranges' to the top
|
||||
model.add(0, "Oranges");
|
||||
</code></pre>
|
||||
|
||||
Sometimes, you want to only let the user select one item. At the end, don’t forget to add the component to the screen!
|
||||
|
||||
</code></pre>
|
||||
|
||||
Sometimes, you want to only let the user select one item. At the end, don’t forget to add the component to the screen!
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
this.add(sp);
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/JList.png" alt="" width="77" height="53" class="alignnone size-full wp-image-2224" />
|
||||
|
||||
### JComboBox
|
||||
|
||||
To create a dropdown list of different options, consider using a JComboBox.
|
||||
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/JList.png" alt="" width="77" height="53" class="alignnone size-full wp-image-2224" />
|
||||
|
||||
### JComboBox
|
||||
|
||||
To create a dropdown list of different options, consider using a JComboBox.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
JComboBox cb = new JComboBox();
|
||||
cb.addItem("Select Food Option");
|
||||
|
@ -200,6 +202,6 @@ cb.addItem("Hot Dog");
|
|||
cb.addItem("Steak");
|
||||
// Add it to the screen
|
||||
this.add(cb);
|
||||
</code></pre>
|
||||
|
||||
</code></pre>
|
||||
|
||||
<img src="https://brandonrozek.com/wp-content/uploads/2017/06/JComboBox.png" alt="" width="153" height="24" class="alignnone size-full wp-image-2223" srcset="https://brandonrozek.com/wp-content/uploads/2017/06/JComboBox.png 153w, https://brandonrozek.com/wp-content/uploads/2017/06/JComboBox-150x24.png 150w" sizes="(max-width: 153px) 100vw, 153px" />
|
|
@ -1,45 +1,47 @@
|
|||
---
|
||||
id: 2192
|
||||
title: Using System Themes In Java Swing
|
||||
date: 2017-06-05T20:36:22+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2192
|
||||
permalink: /2017/06/using-system-themes-java-swing/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:4:"none";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "161478693279"
|
||||
mf2_syndication:
|
||||
- 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/871828083459936257";}'
|
||||
kind:
|
||||
- article
|
||||
---
|
||||
The default theme for Java Swing components is a cross-platform theme called “Metal”. I use the Adapta theme for GTK on Linux and this theme does not match at all what my other GUI applications look like. So here, I will describe a simple way to utlize already existent system themes in Java Swing applications.
|
||||
|
||||
<!--more-->
|
||||
|
||||
### Solution
|
||||
|
||||
In the init method of your java application, place the following code.
|
||||
|
||||
---
|
||||
id: 2192
|
||||
title: Using System Themes In Java Swing
|
||||
date: 2017-06-05T20:36:22+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2192
|
||||
aliases:
|
||||
- /2017/06/using-system-themes-java-swing/
|
||||
permalink: /2017/06/using-system-themes-java-swing/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:4:"none";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "161478693279"
|
||||
mf2_syndication:
|
||||
- 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/871828083459936257";}'
|
||||
kind:
|
||||
- article
|
||||
---
|
||||
The default theme for Java Swing components is a cross-platform theme called “Metal”. I use the Adapta theme for GTK on Linux and this theme does not match at all what my other GUI applications look like. So here, I will describe a simple way to utlize already existent system themes in Java Swing applications.
|
||||
|
||||
<!--more-->
|
||||
|
||||
### Solution
|
||||
|
||||
In the init method of your java application, place the following code.
|
||||
|
||||
<pre class='language-java'><code class='language-java'>
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager
|
||||
.getSystemLookAndFeelClassName());
|
||||
} catch(Exception e) {}
|
||||
</code></pre>
|
||||
|
||||
Here the application will attempt to look up the system theme and set that as the default styles for the Swing components. If the lookup fails, then it will default back to the metal theme.
|
||||
|
||||
For more information, check out this page from [Oracle](http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html).
|
||||
|
||||
### Discussion
|
||||
|
||||
If it is so easy to set up applications that look native to each desktop environment, why not have that by default? With the cross platform metal theme, you can ensure that the style of your application is the same across all the operating systems. In this fashion, you don’t need to worry about spacing between components and have full control of the “look and feel” of your application.
|
||||
|
||||
</code></pre>
|
||||
|
||||
Here the application will attempt to look up the system theme and set that as the default styles for the Swing components. If the lookup fails, then it will default back to the metal theme.
|
||||
|
||||
For more information, check out this page from [Oracle](http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html).
|
||||
|
||||
### Discussion
|
||||
|
||||
If it is so easy to set up applications that look native to each desktop environment, why not have that by default? With the cross platform metal theme, you can ensure that the style of your application is the same across all the operating systems. In this fashion, you don’t need to worry about spacing between components and have full control of the “look and feel” of your application.
|
||||
|
||||
Since I am used to development for the web, I don’t have strong motivation to have an application look the same on all platforms. I prefer the application to match the system theme and look like it was built for the platform that I am on. One loses partial control on the presentation of your application across different desktop environmnets, but with a strong layout, it is possible to make it look organized and integrated.
|
|
@ -5,6 +5,8 @@ date: 2017-08-28T17:12:00+00:00
|
|||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2236
|
||||
aliases:
|
||||
- /2017/08/escape-sequences-java/
|
||||
permalink: /2017/08/escape-sequences-java/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
|
@ -28,12 +30,12 @@ Sometimes you want to format your outputs. This is a quick cheatsheet containing
|
|||
<th class="tg-yw4l">
|
||||
Character
|
||||
</th>
|
||||
|
||||
|
||||
<th class="tg-yw4l">
|
||||
Escape Sequence
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
Newline
|
||||
|
@ -43,7 +45,7 @@ Sometimes you want to format your outputs. This is a quick cheatsheet containing
|
|||
\n
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
Tab
|
||||
|
@ -53,7 +55,7 @@ Sometimes you want to format your outputs. This is a quick cheatsheet containing
|
|||
\t
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
Backspace
|
||||
|
@ -63,7 +65,7 @@ Sometimes you want to format your outputs. This is a quick cheatsheet containing
|
|||
\b
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
Double Quote
|
||||
|
@ -73,7 +75,7 @@ Sometimes you want to format your outputs. This is a quick cheatsheet containing
|
|||
\”
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
Single Quote
|
||||
|
@ -83,7 +85,7 @@ Sometimes you want to format your outputs. This is a quick cheatsheet containing
|
|||
\’
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
Backslash
|
||||
|
|
|
@ -1,127 +1,129 @@
|
|||
---
|
||||
id: 2241
|
||||
title: Obtaining Command Line Input in Java
|
||||
date: 2017-08-28T17:37:59+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2241
|
||||
permalink: /2017/08/obtaining-command-line-input-java/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:4:"none";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "164717769554"
|
||||
mf2_mp-syndicate-to:
|
||||
- 'a:1:{i:0;s:4:"none";}'
|
||||
kind:
|
||||
- note
|
||||
---
|
||||
To obtain console input for your program you can use the <code class="language-java">Scanner</code> class
|
||||
|
||||
First import the relevant library
|
||||
|
||||
---
|
||||
id: 2241
|
||||
title: Obtaining Command Line Input in Java
|
||||
date: 2017-08-28T17:37:59+00:00
|
||||
author: Brandon Rozek
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2241
|
||||
aliases:
|
||||
- /2017/08/obtaining-command-line-input-java/
|
||||
permalink: /2017/08/obtaining-command-line-input-java/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}'
|
||||
mf2_syndicate-to:
|
||||
- 'a:1:{i:0;s:4:"none";}'
|
||||
mf2_cite:
|
||||
- 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}'
|
||||
tumblr_post_id:
|
||||
- "164717769554"
|
||||
mf2_mp-syndicate-to:
|
||||
- 'a:1:{i:0;s:4:"none";}'
|
||||
kind:
|
||||
- note
|
||||
---
|
||||
To obtain console input for your program you can use the <code class="language-java">Scanner</code> class
|
||||
|
||||
First import the relevant library
|
||||
|
||||
<pre class="language-java"><code class="language-java">
|
||||
import java.util.Scanner;
|
||||
</code></pre>
|
||||
|
||||
Then create a variable to hold the <code class="language-java">Scanner</code> object
|
||||
|
||||
</code></pre>
|
||||
|
||||
Then create a variable to hold the <code class="language-java">Scanner</code> object
|
||||
|
||||
<pre class="language-java"><code class="language-java">
|
||||
Scanner input;
|
||||
input = new Scanner(System.in);
|
||||
</code></pre>
|
||||
|
||||
Inside the parenthesis, the <code class="language-java">Scanner</code> binds to the System input which is by default the console
|
||||
|
||||
The new varible <code class="language-java">input</code> now has the ability to obtain input from the console. To do so, use any of the following methods
|
||||
|
||||
<table class="tg">
|
||||
<tr>
|
||||
<th class="tg-yw4l">
|
||||
Method
|
||||
</th>
|
||||
|
||||
<th class="tg-yw4l">
|
||||
What it Returns
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
next()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
The next space seperated string from the console
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
nextInt()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
An integer if it exists from the console
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
nextDouble()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
A double if it exists from the console
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
nextFloat()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
A float if it exists from the console
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
nextLine()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
A string up to the next newline character from the console
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
hasNext()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
Returns true if there is another token
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
close()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
Unbinds the Scanner from the console
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Here is an example program where we get the user’s first name
|
||||
|
||||
</code></pre>
|
||||
|
||||
Inside the parenthesis, the <code class="language-java">Scanner</code> binds to the System input which is by default the console
|
||||
|
||||
The new varible <code class="language-java">input</code> now has the ability to obtain input from the console. To do so, use any of the following methods
|
||||
|
||||
<table class="tg">
|
||||
<tr>
|
||||
<th class="tg-yw4l">
|
||||
Method
|
||||
</th>
|
||||
|
||||
<th class="tg-yw4l">
|
||||
What it Returns
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
next()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
The next space seperated string from the console
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
nextInt()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
An integer if it exists from the console
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
nextDouble()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
A double if it exists from the console
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
nextFloat()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
A float if it exists from the console
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
nextLine()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
A string up to the next newline character from the console
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
hasNext()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
Returns true if there is another token
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="tg-yw4l">
|
||||
close()
|
||||
</td>
|
||||
|
||||
<td class="tg-yw4l">
|
||||
Unbinds the Scanner from the console
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Here is an example program where we get the user’s first name
|
||||
|
||||
<pre class="language-java"><code class="language-java">
|
||||
import java.util.Scanner;
|
||||
|
||||
|
|
|
@ -1,69 +1,71 @@
|
|||
---
|
||||
id: 2250
|
||||
title: Identifying Misspelled Words in your Dataset with Hunspell
|
||||
date: 2018-01-22T05:17:16+00:00
|
||||
author: rozek_admin
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2250
|
||||
permalink: /2018/01/identifying-misspelled-words-dataset-hunspell/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:75:"https://cdn-images-1.medium.com/fit/c/200/200/1*06lotWcLMUnKZTN6-Th3IQ.jpeg";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"c0ccd543b7e6";s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:104:"https://medium.com/@brandonrozek/identifying-misspelled-words-in-your-dataset-with-hunspell-c0ccd543b7e6";}'
|
||||
mf2_mp-syndicate-to:
|
||||
- 'a:1:{i:0;s:22:"bridgy-publish_twitter";}'
|
||||
tumblr_post_id:
|
||||
- "169988632939"
|
||||
mf2_syndication:
|
||||
- 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/955308388384235521";}'
|
||||
kind:
|
||||
- article
|
||||
---
|
||||
This article is based on one written by [Markus Konrad](https://datascience.blog.wzb.eu/author/markus_konrad/) at this link <a href='https://datascience.blog.wzb.eu/2016/07/13/autocorrecting-misspelled-words-in-python-using-hunspell/' target='_blank' >https://datascience.blog.wzb.eu/2016/07/13/autocorrecting-misspelled-words-in-python-using-hunspell/</a>
|
||||
|
||||
I assume in this article that you have hunspell and it's integration with python installed. If not, please refer to the article mention above and follow the prerequisite steps.
|
||||
|
||||
This article is inspired from the need to correct misspelled words in the [Dress Attributes Dataset](https://archive.ics.uci.edu/ml/datasets/Dresses_Attribute_Sales). I'll share with you my initial pitfall, and what I ended up doing instead.
|
||||
|
||||
### Background Information
|
||||
|
||||
Misspelled words are common when dealing with survey data or data where humans type in the responses manually. In the Dress Attributes Dataset this is apparent when looking at the sleeve lengths of the different dresses.
|
||||
|
||||
---
|
||||
id: 2250
|
||||
title: Identifying Misspelled Words in your Dataset with Hunspell
|
||||
date: 2018-01-22T05:17:16+00:00
|
||||
author: rozek_admin
|
||||
layout: post
|
||||
guid: https://brandonrozek.com/?p=2250
|
||||
aliases:
|
||||
- /2018/01/identifying-misspelled-words-dataset-hunspell/
|
||||
permalink: /2018/01/identifying-misspelled-words-dataset-hunspell/
|
||||
medium_post:
|
||||
- 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:75:"https://cdn-images-1.medium.com/fit/c/200/200/1*06lotWcLMUnKZTN6-Th3IQ.jpeg";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"c0ccd543b7e6";s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:104:"https://medium.com/@brandonrozek/identifying-misspelled-words-in-your-dataset-with-hunspell-c0ccd543b7e6";}'
|
||||
mf2_mp-syndicate-to:
|
||||
- 'a:1:{i:0;s:22:"bridgy-publish_twitter";}'
|
||||
tumblr_post_id:
|
||||
- "169988632939"
|
||||
mf2_syndication:
|
||||
- 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/955308388384235521";}'
|
||||
kind:
|
||||
- article
|
||||
---
|
||||
This article is based on one written by [Markus Konrad](https://datascience.blog.wzb.eu/author/markus_konrad/) at this link <a href='https://datascience.blog.wzb.eu/2016/07/13/autocorrecting-misspelled-words-in-python-using-hunspell/' target='_blank' >https://datascience.blog.wzb.eu/2016/07/13/autocorrecting-misspelled-words-in-python-using-hunspell/</a>
|
||||
|
||||
I assume in this article that you have hunspell and it's integration with python installed. If not, please refer to the article mention above and follow the prerequisite steps.
|
||||
|
||||
This article is inspired from the need to correct misspelled words in the [Dress Attributes Dataset](https://archive.ics.uci.edu/ml/datasets/Dresses_Attribute_Sales). I'll share with you my initial pitfall, and what I ended up doing instead.
|
||||
|
||||
### Background Information
|
||||
|
||||
Misspelled words are common when dealing with survey data or data where humans type in the responses manually. In the Dress Attributes Dataset this is apparent when looking at the sleeve lengths of the different dresses.
|
||||
|
||||
<pre><code class='language-python' lang='python'>dresses_data['SleeveLength'].value_counts()
|
||||
</code></pre><figure>
|
||||
|
||||
| Word | Frequency |
|
||||
| -------------- | --------- |
|
||||
| sleevless | 223 |
|
||||
| full | 97 |
|
||||
| short | 96 |
|
||||
| halfsleeve | 35 |
|
||||
| threequarter | 17 |
|
||||
| thressqatar | 10 |
|
||||
| sleeveless | 5 |
|
||||
| sleeevless | 3 |
|
||||
| capsleeves | 3 |
|
||||
| cap-sleeves | 2 |
|
||||
| half | 1 |
|
||||
| Petal | 1 |
|
||||
| urndowncollor | 1 |
|
||||
| turndowncollor | 1 |
|
||||
| sleveless | 1 |
|
||||
| butterfly | 1 |
|
||||
| threequater | 1 |</figure>
|
||||
|
||||
Ouch, so many misspelled words. This is when my brain is racking up all the ways I can automate this problem away. Hence my stumbling upon Markus' post.
|
||||
|
||||
### Automagically Correcting Data
|
||||
|
||||
First, I decided to completely ignore what Markus warns in his post and automatically correct all the words in that column.
|
||||
|
||||
To begin the code, let's import and create an instance of the spellchecker:
|
||||
|
||||
</code></pre><figure>
|
||||
|
||||
| Word | Frequency |
|
||||
| -------------- | --------- |
|
||||
| sleevless | 223 |
|
||||
| full | 97 |
|
||||
| short | 96 |
|
||||
| halfsleeve | 35 |
|
||||
| threequarter | 17 |
|
||||
| thressqatar | 10 |
|
||||
| sleeveless | 5 |
|
||||
| sleeevless | 3 |
|
||||
| capsleeves | 3 |
|
||||
| cap-sleeves | 2 |
|
||||
| half | 1 |
|
||||
| Petal | 1 |
|
||||
| urndowncollor | 1 |
|
||||
| turndowncollor | 1 |
|
||||
| sleveless | 1 |
|
||||
| butterfly | 1 |
|
||||
| threequater | 1 |</figure>
|
||||
|
||||
Ouch, so many misspelled words. This is when my brain is racking up all the ways I can automate this problem away. Hence my stumbling upon Markus' post.
|
||||
|
||||
### Automagically Correcting Data
|
||||
|
||||
First, I decided to completely ignore what Markus warns in his post and automatically correct all the words in that column.
|
||||
|
||||
To begin the code, let's import and create an instance of the spellchecker:
|
||||
|
||||
<pre><code class='language-python' lang='python'>from hunspell import HunSpell
|
||||
spellchecker = HunSpell('/usr/share/hunspell/en_US.dic', '/usr/share/hunspell/en_US.aff')
|
||||
</code></pre>
|
||||
|
||||
I modified his `correct_words` function so that it only corrects one word and so I can `apply` it along the `SleeveLength` column.
|
||||
|
||||
</code></pre>
|
||||
|
||||
I modified his `correct_words` function so that it only corrects one word and so I can `apply` it along the `SleeveLength` column.
|
||||
|
||||
<pre><code class='language-python' lang='python'>def correct_word(checker, word, add_to_dict=[]):
|
||||
"Takes in a hunspell object and a word and corrects the word if needed"
|
||||
# Add custom words to the dictionary
|
||||
|
@ -92,47 +94,47 @@ I modified his `correct_words` function so that it only corrects one word and so
|
|||
## Not a string. Return original
|
||||
corrected = word
|
||||
return corrected
|
||||
</code></pre>
|
||||
|
||||
Now let's apply the function over the `SleeveLength` column of the dataset:
|
||||
|
||||
</code></pre>
|
||||
|
||||
Now let's apply the function over the `SleeveLength` column of the dataset:
|
||||
|
||||
<pre><code class='language-python' lang='python'>dresses_data['SleeveLength'] = dresses_data['SleeveLength'].apply(
|
||||
lambda x: correct_word(spellchecker, x))
|
||||
</code></pre>
|
||||
|
||||
Doing so creates the following series:<figure>
|
||||
|
||||
| Word | Frequency |
|
||||
| -------------- | --------- |
|
||||
| sleeveless | 232 |
|
||||
| full | 97 |
|
||||
| short | 96 |
|
||||
| half sleeve | 35 |
|
||||
| three quarter | 17 |
|
||||
| throatiness | 10 |
|
||||
| cap sleeves | 3 |
|
||||
| cap-sleeves | 2 |
|
||||
| Petal | 1 |
|
||||
| butterfly | 1 |
|
||||
| turndowncollor | 1 |
|
||||
| half | 1 |
|
||||
| landownership | 1 |
|
||||
| forequarter | 1 |</figure>
|
||||
|
||||
As you might be able to tell, this process didn't go as intended. `landownership` isn't even a length of a sleeve!
|
||||
|
||||
### Reporting Misspelled Items and Allowing User Intervention
|
||||
|
||||
This is when I have to remember, technology isn't perfect. Instead we should rely on ourselves to identify what the word should be correctly spelled as.
|
||||
|
||||
Keeping that in mind, I modified the function again to take in a list of the data, and return a dictionary that has the misspelled words as the keys and suggestions as the values represented as a list.
|
||||
|
||||
</code></pre>
|
||||
|
||||
Doing so creates the following series:<figure>
|
||||
|
||||
| Word | Frequency |
|
||||
| -------------- | --------- |
|
||||
| sleeveless | 232 |
|
||||
| full | 97 |
|
||||
| short | 96 |
|
||||
| half sleeve | 35 |
|
||||
| three quarter | 17 |
|
||||
| throatiness | 10 |
|
||||
| cap sleeves | 3 |
|
||||
| cap-sleeves | 2 |
|
||||
| Petal | 1 |
|
||||
| butterfly | 1 |
|
||||
| turndowncollor | 1 |
|
||||
| half | 1 |
|
||||
| landownership | 1 |
|
||||
| forequarter | 1 |</figure>
|
||||
|
||||
As you might be able to tell, this process didn't go as intended. `landownership` isn't even a length of a sleeve!
|
||||
|
||||
### Reporting Misspelled Items and Allowing User Intervention
|
||||
|
||||
This is when I have to remember, technology isn't perfect. Instead we should rely on ourselves to identify what the word should be correctly spelled as.
|
||||
|
||||
Keeping that in mind, I modified the function again to take in a list of the data, and return a dictionary that has the misspelled words as the keys and suggestions as the values represented as a list.
|
||||
|
||||
<pre><code class='language-python' lang='python'>def list_word_suggestions(checker, words, echo = True, add_to_dict=[]):
|
||||
"Takes in a list of words and returns a dictionary with mispellt words as keys and suggestions as a list. Also prints it out"
|
||||
# add custom words to the dictionary
|
||||
for w in add_to_dict:
|
||||
checker.add(w)
|
||||
|
||||
|
||||
suggestions = {}
|
||||
for word in words:
|
||||
if isinstance(word, str):
|
||||
|
@ -144,15 +146,15 @@ Keeping that in mind, I modified the function again to take in a list of the dat
|
|||
elif echo:
|
||||
print(word + ": " + "[", ", ".join(repr(i) for i in suggestions[word]), "]")
|
||||
return suggestions
|
||||
</code></pre>
|
||||
|
||||
With that, I can use the function on my data. To do so, I convert the pandas values to a list and pass it to the function:
|
||||
|
||||
</code></pre>
|
||||
|
||||
With that, I can use the function on my data. To do so, I convert the pandas values to a list and pass it to the function:
|
||||
|
||||
<pre><code class='language-python' lang='python'>s = list_word_suggestions(spellchecker, dresses_data['SleeveLength'].values.tolist())
|
||||
</code></pre>
|
||||
|
||||
These are the suggestions it produces:
|
||||
|
||||
</code></pre>
|
||||
|
||||
These are the suggestions it produces:
|
||||
|
||||
<pre><code class='language-python' lang='python'>sleevless: [ 'sleeveless', 'sleepless', 'sleeves', 'sleekness', 'sleeve', 'lossless' ]
|
||||
threequarter: [ 'three quarter', 'three-quarter', 'forequarter' ]
|
||||
halfsleeve: ['half sleeve', 'half-sleeve', 'sleeveless' ]
|
||||
|
@ -163,15 +165,15 @@ sleeevless: [ 'sleeveless', 'sleepless', 'sleeves', '
|
|||
urndowncollor: [ 'landownership' ]
|
||||
thressqatar: [ 'throatiness' ]
|
||||
sleveless: [ 'sleeveless', 'levelness', 'valveless', 'loveless', 'sleepless' ]
|
||||
</code></pre>
|
||||
|
||||
From here, you can analyze the output and do the replacements yourself:
|
||||
|
||||
</code></pre>
|
||||
|
||||
From here, you can analyze the output and do the replacements yourself:
|
||||
|
||||
<pre><code class='language-python' lang='python'>dresses_data['SleeveLength'].replace('sleevless', 'sleeveless', inplace = True)
|
||||
</code></pre>
|
||||
|
||||
### What's the Benefit?
|
||||
|
||||
This is where you ask "What's the difference if it doesn't automatically fix my data?"
|
||||
|
||||
</code></pre>
|
||||
|
||||
### What's the Benefit?
|
||||
|
||||
This is where you ask "What's the difference if it doesn't automatically fix my data?"
|
||||
|
||||
When you have large datasets, it can be hard to individually identify which items are misspelled. Using this method will allow you to have a list of all the items that are misspelled which can let you deal with it in a systematic way.
|
Loading…
Reference in a new issue