Add 'Arrays' lesson to csintro. (#436)

This commit is contained in:
Galen Nickel 2017-07-03 16:16:20 -07:00 committed by Sam El-Husseini
parent 9c6d09ac2f
commit 288f99bdaa
14 changed files with 667 additions and 1 deletions

View File

@ -114,6 +114,12 @@
* [Activity](/courses/csintro/radio/activity) * [Activity](/courses/csintro/radio/activity)
* [Project](/courses/csintro/radio/project) * [Project](/courses/csintro/radio/project)
* [Standards](/courses/csintro/radio/standards) * [Standards](/courses/csintro/radio/standards)
* [Arrays](/courses/csintro/arrays)
* [Overview](/courses/csintro/arrays/overview)
* [Unplugged](/courses/csintro/arrays/unplugged)
* [Activity](/courses/csintro/arrays/activity)
* [Project](/courses/csintro/arrays/project)
* [Standards](/courses/csintro/arrays/standards)
## #reference ## #reference

View File

@ -41,5 +41,5 @@ UNDER CONSTRUCTION: We are still migrating the CSIntro content to this format...
8. [Booleans](/courses/csintro/booleans) 8. [Booleans](/courses/csintro/booleans)
9. [Bits, Bytes, and Binary](/courses/csintro/binary) 9. [Bits, Bytes, and Binary](/courses/csintro/binary)
10. [Radio](/courses/csintro/radio) 10. [Radio](/courses/csintro/radio)
11. Arrays 11. [Arrays](/courses/csintro/arrays)
12. Independent Final Project 12. Independent Final Project

View File

@ -0,0 +1,29 @@
# Arrays
This lesson covers storing and retrieving data in an ordered fashion using Arrays. Introduces JavaScript as an alternate way of creating and modifying code. Uses a melody as a list/array of notes.
 
## Lesson objectives
Students will...
* Explain the steps they would take to sort a series of numbers
* Recognize three common sorting algorithms
* Learn
* Apply
 
## Lesson structure
* Introduction: Arrays
* Unplugged Activity: Different Sorts of People
* Micro:bit Activity: Headband Charades, Starry Starry Night
* Project: Make a Musical Instrument
* Assessment: Rubric
* Standards: Listed
 
## Lesson plan
1. [**Overview**: Arrays](/courses/csintro/arrays/overview)
2. [**Unplugged**: Different sorts of people](/courses/csintro/arrays/unplugged)
3. [**Activity**: Headband charades](/courses/csintro/arrays/activity)
4. [**Project**: Musical instrument ](/courses/csintro/arrays/project)
## Related standards
[Targeted CSTA standards](/courses/csintro/arrays/standards)

View File

@ -0,0 +1,188 @@
## Activity: Headband charades
Create an array of words that can be used as part of a charades-type game.
This activity is based on a very popular phone app invented by Ellen DeGeneres (https://bits.blogs.nytimes.com/2013/05/03/ellen-degeneres-iphone-game/).
![Heads up game](/static/courses/csintro/arrays/heads-up-game.jpg)
* Create a new variable and give it a name like arrayWords.
* Insert a 'set' variable block into the 'on start' block.
* Change the default variable name to this new variable name.
* From the Array Toolbox drawer, drag a 'create array' block to the coding workspace.
* Attach this array block to the end of the 'set' variable block.
```blocks
let arrayWords = ["", ""]
```
Notice that the array comes with 2 string blocks. Well want more for our charades game.
* Click on the blue gear-wheel icon in the top left corner of the 'create array' block.
* From the pop up window, add as many values (elements) as you'd like to the array block by dragging the value block from the left side of the window to the array block on the right side of the window.
* For now, well add 4 more values for a total of 6 values.
![Add values to array](/static/courses/csintro/arrays/array-add-value.png)
* Drag 4 string blocks from the Text Toolbox drawer, and place them in the empty array slots.
```blocks
let arrayWords = ["", "", "", "", "", "", ""]
```
* Fill each string with one word. Choose words that will be fun for a game of charades.
Example:
```blocks
let arrayWords = ["cat", "guitar", "flashlight", "cupcake", "tree", "frisbee"]
```
Now, we need a way to access one word at a time from this array of words.
* We can use the 'show string' block from the Basic Toolbox drawer, and the 'on screen up' event handler from the Input Toolbox drawer (this is a drop-down menu choice of the 'on shake' block) to tell the micro:bit to display a word when we tilt the micro:bit up.
* For this version, well display the words one at a time in the order they were first placed into the array.
* Well use the index of the array to keep track of what word to display at any given time, so you'll need to create an 'index' variable.
```block
let arrayWords: string[] = []
let index = 0
input.onGesture(Gesture.ScreenUp, () => {
basic.showString(arrayWords[index])
})
```
* To start the game with the index at zero, add a 'set' variable block to the 'on' start block.
* Next, add the following:
>* an image as a placeholder for when the program has started. Since charades is a guessing game, we made one that looks like a question mark (?),
* a countdown to the first word using show number blocks and pause blocks
* And show the first word in the array
```blocks
let index = 0
let arrayWords: string[] = []
 
arrayWords = ["cat", "guitar", "flashlight", "cupcake", "tree", "frisbee"]
index = 0
basic.showLeds(`
. # # # .
. . . # .
. . # # .
. . . . .
. . # . .
`)
basic.pause(100)
basic.showNumber(3)
basic.pause(100)
basic.showNumber(2)
basic.pause(100)
basic.showNumber(1)
basic.showString(arrayWords[index])
```
So far we have a start to our game and a way to display the first word.
Once that word has been guessed (or passed), we need a way to advance to the next word in the array.
* We can do this by changing the index of the array with the 'on screen down' event handler from the Input Toolbox drawer (this is a drop-down menu choice of the 'on shake' block) to advance to the next word when we tilt the micro:bit down.
```block
let index = 0
input.onGesture(Gesture.ScreenDown, () => {
index += 1
})
```
We have a limited number of elements in our array, so to avoid an error, we need to check and make sure we are not already at the end of the array before we change the index.
 
* Under the Arrays Toolbox drawer, drag out a 'length of' block. The 'length of' block returns the number of items (elements) in an array. For our array, the length of block will return the value 6.
* But because computer programmers start counting at zero, the index of the final (6th) element is 5.
 
Some pseudocode for our algorithm logic:
* When the player places the micro:bit screen down:
>Check the current value of the index.
>> **If:** the current value of the index is less than the length of the array minus one (see **array bounds** note),<br/>
**Then:** change the value of the index by one,<br/>
**Else:** indicate that it is the end of the game.
## ~hint
**Array bounds**
Our array has a length 6, so this will mean that as long as the current value of the index is less than 5, we will change the array by one.
Using less than the length of the array minus one instead of the actual numbers for our array makes this code more flexible and easier to maintain. We can easily add more elements to our array and not have to worry about changing numbers elsewhere in the code.
## ~ 
We can put this all together with an 'if...then...else' block and a 'less than' comparison block from the Logic Toolbox drawer, a subtraction block from the Math Toolbox drawer, and a 'game over' block from the Game Toolbox drawer (located under the Advanced menu).
```blocks
let index = 0
let arrayWords: string[] = []
input.onGesture(Gesture.ScreenDown, () => {
   if (index < arrayWords.length - 1) {
       index += 1
   } else {
       game.gameOver()
   }
})
```
To make our game more polished, well add 2 more blocks for smoother game play.
* In case a word is already scrolling on the screen when a player places the micro:bit screen down, we can stop this animation and clear the screen for the next word by using a 'stop animation' block from the Led More Toolbox drawer, and a 'clear screen' block from the Basic More Toolbox drawer.
```blocks
let index = 0
let arrayWords: string[] = []
input.onGesture(Gesture.ScreenDown, () => {
led.stopAnimation()
basic.clearScreen()
if (index < arrayWords.length - 1) {
index += 1
} else {
game.gameOver()
}
})
```
## Game Play
There are different ways you can play charades with our program. Here is one way you can play with a group of friends.
* With the micro:bit on and held so Player A cannot see the screen, another player starts the program to see the first word.
* The other players act out this word charades-style for Player A to guess.
* When Player A guesses correctly or decides to pass on this word, a player places the micro:bit screen down.
* When ready for the next word, a player turns the micro:bit screen up. Play continues until all the words in the array have been used.
 
## Mod this!
* Add a headband to hold the micro:bit on the Players' foreheads (using cardboard, paper, rubber bands, etc.)
* Add a way to keep score
* Keep track of the number of correct guesses and passes
* Add a time limit
 
Headband Charades Complete Program (simple version - no time limit or scoring):
 
```blocks
let index = 0
let arrayWords: string[] = []
input.onGesture(Gesture.ScreenUp, () => {
   basic.showString(arrayWords[index])
})
input.onGesture(Gesture.ScreenDown, () => {
   led.stopAnimation()
   basic.clearScreen()
   if (index < arrayWords.length - 1) {
       index += 1
   } else {
       game.gameOver()
   }
})
arrayWords = ["cat", "guitar", "flashlight", "cupcake", "tree", "frisbee"]
index = 0
basic.showLeds(`
   . # # # .
   . . . # .
   . . # # .
   . . . . .
   . . # . .
   `)
basic.pause(100)
basic.showNumber(3)
basic.pause(100)
basic.showNumber(2)
basic.pause(100)
basic.showNumber(1)
basic.showString(arrayWords[index])
```

View File

@ -0,0 +1,62 @@
# Introduction
Any collector of coins, fossils, or baseball cards knows that at some point you need to have a way to organize everything so you can find things. For example, a rock collector might have a tray of specimens numbered like this:
![Rock collection is an array](/static/courses/csintro/arrays/rock-collection.png)
Every rock in the collection needs its own storage space, and a unique address so you can find it later.
 
As your MakeCode programs get more and more complicated, and require more variables to keep track of things, you will want to find a way to store and organize all of your data. MakeCode provides a special category for just this purpose, called an Array.
 
* Arrays can store numbers, strings (words), or sprites. They can also store musical notes.
* Every spot in an array can be identified by its index, which is a number that corresponds to its location in the array. The first slot in an array is index 0, just like our rock collection above.
* The length of an array refers to the total number of items in the array, and the index of the last element in an array is always one less than its length (because the array numbering starts at zero.)
 
In MakeCode, you can create an array by assigning it to a variable. The Array blocks can be found under the Advanced Toolbox menu.
![Arrays block menu](/static/courses/csintro/arrays/arrays-menu.png)
```blocks
let list = [4, 2, 5, 1, 3]
```
The code above creates an empty array called list, then fills it with five numbers, indexed from 0 to 4. The index of the first value (4) is 0. The index of the second value (2) is 1. The index of the last value (3) is 4.
 
You can get items out of the array by specifying its index like this:
```blocks
let list = [4, 2, 5, 1, 3]
input.onButtonPressed(Button.A, () => {
basic.showNumber(list[0])
})
``` 
The code above takes the first element in the array (the value at index 0) and shows it on the screen.
 
There are lots of other blocks in the Arrays Toolbox drawer. The next few Activities will introduce you to them.
 
## Discussion
* Ask your students if any of them collects anything. What is it? Comic books, cards, coins, stamps, books, etc.
* How big is the collection?
* How is it organized?
* Are the items sorted in any way?
* How would you go about finding a particular item in the collection?
 
In the discussion, see if you can explore the following array vocabulary words in the context of kids personal collections.
* Length: the total number of items in the collection
* Sort: Items in the collection are ordered by a particular attribute (e.g., date, price, name)
* Index: A unique address or location in the collection
* Type: The type of item being stored in the collection
 
## References
Once you start saving lots of different values in an array, you will probably want to have some way to sort those values. Many languages already implement a sorting algorithm that students can call upon as needed. However, understanding how those different sorting algorithms work is an important part of computer science, and as students go on to further study they will learn other algorithms, as well as their relative efficiency.
There are some good array sorting videos:
* Visually displays a number of different types of sorts: https://www.youtube.com/watch?v=kPRA0W1kECg
* Bubble-sort with Hungarian folk dance: https://youtu.be/lyZQPjUT5B4
* Select-sort with Gypsy folk dance: https://youtu.be/Ns4TPTC8whw
* Insert-sort with Romanian folk dance: https://youtu.be/ROalU379l3U
![Folk dance sorting](/static/courses/csintro/arrays/folk-dance-sorting.png)

View File

@ -0,0 +1,123 @@
# Project: Musical instrument
This is a project in which students are challenged to create a musical instrument that uses arrays to store sequences of notes. The array of notes can be played when an input occurs, such as one of the buttons being pressed, or if one or more of the pins is activated.
 
Ideally, the micro:bit should be mounted in some kind of housing, perhaps a guitar shape or a music box. Start by looking at different kinds of musical instruments to get a sense of what kind of shape you might want to build around your micro:bit.
![micro:bit guitar](/static/courses/csintro/arrays/microbit-guitar.png)
Here are some examples of guitars that were made out of cardboard and colored, patterned duct tape that you can buy in craft stores.
## Example Guitar Code
This is an example of a project that uses the micro:bit accelerometer to play different tones when the guitar is held and tilted while playing. Pressing the A button will save the current tone to an array. After ten tones, a repeating melody will be performed. Press the B button to clear the array and start over.
## Song-maker
```blocks
let currentNote = 0
let list: number[] = []
basic.forever(() => {
if (list.length < 10) {
currentNote = input.acceleration(Dimension.X) + 1300
music.ringTone(currentNote)
} else {
basic.showLeds(`
. . # . .
. # . # .
# . . . #
. # . # .
. . # . .
`)
for (let value of list) {
music.playTone(value, music.beat(BeatFraction.Whole))
}
}
})
input.onButtonPressed(Button.A, () => {
if (list.length < 10) {
list.push(currentNote)
basic.showNumber(10 - list.length)
}
})
input.onButtonPressed(Button.B, () => {
list = []
basic.clearScreen()
})
```
## Using arrays with musical notes
You can create an array of notes by attaching Music blocks to an array. Musical notes are described in words (e.g., Middle C, High C) but they are actually numbers. You can do Math operations on those numbers to change the pitch of your song.
 
Here is an example of how to create an array with musical notes. Button A plays every note in the array. Button B plays the notes at twice the frequency (but doesn't alter the original notes.)
```blocks
let list: number[] = []
let value = 0
input.onButtonPressed(Button.A, () => {
for (let value of list) {
music.playTone(value, music.beat(BeatFraction.Whole))
}
basic.pause(1000)
})
input.onButtonPressed(Button.B, () => {
for (let value of list) {
music.playTone(value * 2, music.beat(BeatFraction.Whole))
}
basic.pause(1000)
})
list = [262, 392, 330, 392, 262]
```
Remember that a 'for element value of list' loop makes a temporary copy of the value, so even if you change a value, it will not change the original element in the array. If students want to permanently change the values in their array (transpose music to increasingly higher keys, for example) they can use a for loop like this:
```blocks
let list: number[] = []
input.onButtonPressed(Button.AB, () => {
for (let index = 0; index <= list.length - 1; index++) {
list[index] = list[index] * 2
}
})
```
## Reflection
Have students write a reflection of about 150300 words, addressing the following points:
* Explain how you decided on your musical instrument. What brainstorming ideas did you come up with?
* What properties does it share with a real musical instrument? What is unique?
* Describe the type of array you used (Numbers, Strings, or Notes) and how it functions in your project.
* What was something that was surprising to you about the process of creating this program?
* Describe a difficult point in the process of designing this program, and explain how you resolved it.
* What feedback did your beta testers give you? How did that help you improve your musical instrument?
## Assessment
**Competency scores**: 4, 3, 2, 1
### Array
**4 =** Stores and iterates through each element of the array successfully.<br/>
**3 =** Stores each element of the array successfully.<br/>
**2 =** Array skips values or has other problems with storing and/or retrieving elements.<br/>
**1 =** Array doesn't work at all or no array present.
### micro:bit program
**4 =** The program:<br/>
`*` Uses at least one array in a fully integrated and meaningful way<br/>
`*` Compiles and runs as intended<br/>
`*` Meaningful comments in code<br/>
**3 =** Uses an array in a tangential way that is peripheral to function of project and/or program lacks 1 of the required elements.<br/>
**2 =** Array is poorly implemented and/or peripheral to function of project, and/or lacks 2 of the required elements.<br/>
**1 =** micro:bit program lacks 3 or more of the required elements.
### Collaboration reflection
**4 =** Reflection piece includes:<br/>
`*` Brainstorming ideas<br
`*` Construction<br/>
`*` Programming<br/>
`*` Beta testing<br/>
**3 =** Reflection piece lacks 1 of the required elements.<br/>
**2 =** Reflection piece lacks 2 of the required elements.<br/>
**1 =** Reflection piece lacks 3 of the required elements.

View File

@ -0,0 +1,10 @@
# Standards
## CSTA K-12 Computer Science Standards
* CT.L1:6-02 Develop a simple understanding of an algorithm using computer-free exercise
* CPP.L1:6-05 Construct a program as a set of step-by-step instructions to be acted out
* 2-A-2-1 Solicit and integrate peer feedback as appropriate to develop or refine a program
* 2-A-6-10 Use an iterative design process (e.g., define the problem, generate ideas, build, test, and improve solutions) to solve problems, both independently and collaboratively.
* CT.L3B-06 Compare and contrast simple data structures and their uses (e.g., arrays and lists).
* CL.L2-05 Implement problem solutions using a programming language, including: looping behavior, conditional statements, logic, expressions, variables, and functions.

View File

@ -0,0 +1,248 @@
## Unplugged: Different sorts of people
In this activity, you will demonstrate different kinds of sorting methods on your own students. This is an unplugged activity, so your students will be standing at the front of the room. If you or your students are curious to see what these different sorts look like in code, we have included a MakeCode version of each algorithm in this lesson, for you to explore if you choose.
 
## Materials
* Sheets of paper numbered 110, one large printed number to a page
## Set Up
* Have up to ten students (the Sortees) stand up at the front of the classroom. Ask another student to volunteer to be the Sorter.
* Mix up the order of the papers and give each student a piece of paper with a number on it. They should hold the paper facing outward so their number is visible. Each of these students is like an element in an array.
 
## Initial Sort
* Ask the Sorter to place the students in order by directing them to move, one at a time, to the proper place.
* Once the students are sorted, ask students the following:
>*  How did she sort you into the right order?
* Did you see a pattern?
* What did she do?
 
Try to get students to be as precise as possible in explaining their thinking. Sometimes it helps to put the steps on the board, in an algorithm:
* _First, she went to the first student, then put him in the right place._
* _Then she went to each of the next students and put them in the right place._
 
Ask for clarification when necessary: _What does it mean when you say “put them in the right place”?_
 
_To Put Someone in the Right Place:_
_Bring the person to the front of the line and then compare that persons number with the first persons number. If its larger, then move that person to the right. K eep doing this as long as the persons number is larger than the person on the right._
 
## Some Different Types of Sorts
In computer science, there are certain common strategies, or algorithms, for sorting a collection of values. Try acting out each of these different sorts with your students.
 
## Bubble Sort
Compare the first two students. If the student on the right is smaller than the student on the left, they should swap places. Then compare the second and third students. If the student on the right is smaller than the student on the left, they should swap places. When you reach the end, start over at the beginning again. Continue in this way until you make it through the entire row of students without swapping anybody.
 
### In pseudocode:
1. Create a variable called counter.
2. Set the counter to zero.
3. Go through the entire array.
4. If the value you are considering is greater than the value to its right:
>1. Swap them
>2. Add one to counter
5. Repeat steps 2 through 4 as long as counter is greater than zero.
 
### In MakeCode:
**Note:** Press B to display the array visually. The length of each vertical bar represents each number in the array, from left to right. Press A to sort the array using Bubble Sort. Press A + B to generate new random numbers for the array.
```blocks
let temp = 0
let row = 0
let list: number[] = []
let counter = 0
let column = 0
let index = 0
input.onButtonPressed(Button.AB, () => {
for (let index = 0; index <= 4; index++) {
list[index] = Math.random(5) + 1
}
})
input.onButtonPressed(Button.B, () => {
basic.clearScreen()
for (let column = 0; column <= 4; column++) {
row = 0
while (row < list[column]) {
led.plot(column, 4 - row)
row += 1
}
}
})
input.onButtonPressed(Button.A, () => {
while (counter > 0) {
counter = 0
for (let index = 0; index <= 3; index++) {
if (list[index] > list[index + 1]) {
temp = list[index]
list[index] = list[index + 1]
list[index + 1] = temp
counter += 1
}
basic.clearScreen()
for (let column = 0; column <= 4; column++) {
row = 0
while (row < list[column]) {
led.plot(column, 4 - row)
row += 1
}
basic.pause(100)
}
}
}
})
basic.showLeds(`
# # # . .
# . . # .
# # # . .
# . . # .
# # # . .
`)
list = [4, 2, 5, 1, 3]
counter = 1
```
## Selection Sort
Take the first student on the left and consider that persons number the smallest number you have found so far. If the next person in line has a number that is smaller than that number, then make that persons number your new smallest number and continue in this way until you reach the end of the line of students. Then, move the person with the smallest number all the way to the left. Then start over from the second person in line. Keep going, finding the smallest number each time, and making that person the rightmost person in the sorted line of students.
 
### In pseudocode:
1. Find the smallest unsorted value in the array.
2. Swap that value with the first unsorted value in the array.
3. Repeat steps 1 and 2 while the number of unsorted items is greater than zero.
 
### In MakeCode:
**Note:** The inner loop gets smaller as the sorting algorithm runs because the number of unsorted items decreases as you go. The index that the inner loop starts at needs to change as the number of sorted items increases, which is why we have to use a separate counter (item) and compute j every time through the inner loop.
```blocks
let temp = 0
let j = 0
let min = 0
let row = 0
let list: number[] = []
let item = 0
let column = 0
input.onButtonPressed(Button.B, () => {
basic.clearScreen()
for (let column = 0; column <= 4; column++) {
row = 0
while (row < list[column]) {
led.plot(column, 4 - row)
row += 1
}
}
})
input.onButtonPressed(Button.AB, () => {
for (let index = 0; index <= 4; index++) {
list[index] = Math.random(5) + 1
}
})
input.onButtonPressed(Button.A, () => {
item = 1
for (let i = 0; i <= 3; i++) {
min = i
for (let inner = 0; inner <= 3 - i; inner++) {
j = inner + item
if (list[j] < list[min]) {
min = j
}
}
if (min != i) {
temp = list[min]
list[min] = list[i]
list[i] = temp
}
item += 1
basic.clearScreen()
for (let column = 0; column <= 4; column++) {
row = 0
while (row < list[column]) {
led.plot(column, 4 - row)
row += 1
}
basic.pause(100)
}
}
})
basic.showLeds(`
. . # # .
. # . . .
. . # . .
. . . # .
. # # . .
`)
list = []
list = [4, 2, 5, 1, 3]
min = 1
```
## Insertion Sort
Take the first student on the left and consider that person sorted. Next, take the next student and compare him to the first student in the sorted section. If he is greater than the first student, then place him to the right of the student in the sorted section. Otherwise, place him to the left of the student in the sorted section. Continue down the line, considering each student in turn and then moving from left to right along the students in the sorted section until you find the proper place for each student to go, shifting the other students to the right to make room.
 
### In pseudocode:
1. For each element in the unsorted section of the list, compare it against each element in the sorted section of the list until you find its proper place.
2. Shift the other elements in the sorted list to the right to make room.
3. Insert the element into its proper place in the sorted list.
 
### In MakeCode:
```blocks
let j = 0
let row = 0
let element = 0
let list: number[] = []
input.onButtonPressed(Button.A, () => {
for (let i = 0; i <= 4; i++) {
element = list[i]
j = i
while (j > 0 && list[j - 1] > element) {
list[j] = list[j - 1]
j += -1
list[j] = element
}
basic.clearScreen()
for (let column2 = 0; column2 <= 4; column2++) {
row = 0
while (row < list[column2]) {
led.plot(column2, 4 - row)
row += 1
}
basic.pause(100)
}
}
})
input.onButtonPressed(Button.AB, () => {
for (let index = 0; index <= 4; index++) {
list[index] = Math.random(5) + 1
}
})
input.onButtonPressed(Button.B, () => {
basic.clearScreen()
for (let column = 0; column <= 4; column++) {
row = 0
while (row < list[column]) {
led.plot(column, 4 - row)
row += 1
}
}
})
list = []
basic.showLeds(`
. # # # .
. . # . .
. . # . .
. . # . .
. # # # .
`)
list = []
list = [4, 2, 5, 1, 3]
j = 1
```
## Sidebar
In 2008, Illinois Senator Barack Obama was interviewed by Googles CEO Eric Schmidt, who asks him a computer science interview question. Watch as the interview doesnt go exactly as planned…
https://www.youtube.com/watch?v=k4RRi_ntQc8
[Barak Obama interviewed by Eric Schmidt](https://www.youtube.com/watch?v=k4RRi_ntQc8)

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB