Shared project by: Paweł Dąbrowski, Przemysław Tyczyno and Rafał Pajdak
Multistage coding exercise based on JetBrains Academy project https://hyperskill.org/projects/58?track=1
What we are learning here
Development progress
What is this project actually?
Workflow
Braching instructions
Specification
- working in small group on one project
- simple documentation
- branching and issue tracking
Project suspended.
We are building an App which simulates transmission of information via internet.
There are three modules here:
Name | Description |
---|---|
Encoder | wraps an input message, using a strategy to prevent information loss |
Transmitter | generates random noise in each section of transmitted message |
Decoder | recovers the original input, using loss-prevention strategies |
Each Stage implement another layer of an App:
Stage | Strategy | Name | Remarks |
---|---|---|---|
1 | Symbol | Encoder | duplicating chars in String |
2 | Symbol | Transmitter | |
3 | Symbol | Decoder | |
4 | Symbol | Integeration | connecting stages 1-3 into an App |
5 | Bitwise | Encoder | operating on bit-level in String |
6 | Bitwise | Transmitter | |
7 | Bitwise | Decoder | |
7.1 | refactor | ||
8 | Bitwise | Integeration | connecting stages 5-7 |
- Project is divided into small Stages, each has some added value to the final project. Stages are not independent, but they contribute to final stage of project.
- Each Stage has some issues, smaller steps to accomplish - at least: tests (we try to follow TDD), documentation and implementation.
- Issues are created on Project page in column To do and assigned to a developer.
- When we start working on issue, we change its status from To do to In progress.
- When the code is done, we change status to In review and wait for acceptance of other members.
- If code is accepted, merge is done by reviewer. Change issue status to Done
- if code is not accepted, add comments and change status to In progress
- Each branch is named for issue number and short label, describing feature. If there is no issue connected to your task - create one.
- We are pulling our code to dev branch.
- After completing new stage, there is a release pull from dev to main.
Example name of branch:
40-newBranchesDescription
Stage 1 - symbol level Encoder
Stage 2 - symbol level Transmitter
Stage 3 - symbol level Decoder
Stage 4 - App operating on implementations from Stages 1-3
Stage 5 - bit level Encoder
Stage 6 - bit level Transmitter
Stage 7 - bit level Decoder
Introduction - create a method encode() in class Stage1. Method takes a string as an input and return another string with tripled each character.
For example:
abc -> aaabbbccc
test -> ttteeesssttt
Create a method send() in class Stage2. Method takes a string (it should be each character repeat 3 times, for example instead of d - ddd) as an input and return another string, with changed one char of each of 3 chars blocks.
For example
aaabbbccc -> axabtbcoc
sssooosss -> ssqsoooss
Create a method decode() in class Stage3. Method takes a string (as output from Stage2.send()) and tries to recover original message. Strategy is to check each section of 3 chars, because only one char per 3 is corrupted.
For example:
aaP -> a
TToE_E!SSttO -> TESt
Connect actions from Stages 1-3 to App class. Use interfaces as described below:
Encoder: String encode(String)
Transmitter: String send(String)
Decoder: String decode()
Interface implementantations come from Stages1-3.
Implement Encoder on bitwise level. We will work on every char of String message.
Please remember, that Strings are char arrays, and chars are just numbers "casted" on ASCII table values (it is a simplification but for this project should be sufficient).
We will manipulate every char (number) in String input. For consistency we count bits from left. Every bit of message is divided on smaller parts, like this:Here is sample byte of information (input):
01011010
(bits are symbolized below by letters:
abcdefgh)Take 3 first bits (from left) and add 1 parity bit for verification.
Parity bits (on positions 7-8 from left) are loss-prevention strategy. We calculate them by adding 3 significant bits:
010 - odd (parity bit = 1)
000 - even (parity bit = 0)
110 - even (parity bit = 0)
111 - odd (parity bit = 1)
After this, you have 3 bits from input + 1 parity bit: abcX
Double all bits to form first byte of output:
aabbccXX
Then take next three bits from input and transfer them in similar way:
ddeeffXX
And at last, the remaining bits. If there are less than 3 bits remaining, use 0 to fill blanks.
gghh00XX
Your input was one byte (01011010) but output is three bytes (00110011 11110000 11000011).
Implement Transmitter on bitwise level. Every byte of message gets 1 of their bit (at random position) changed.
Decoder implemented on bitwise level.
On input we get string send by Transmitter module. Each byte consist of paired bits. One pair of bits contain error, introduced by Transmitter.
Example input:
00110001
01110000
11011100
To decode original message, reduce each pair of bits to one bit:
00 -> 0
11 -> 1
10/01 -> ? (transmission error)
This allows you to read original message, but it may contain some errors:
00110001 -> 010?
01110000 -> ?100
11011100 -> 1?10
When error appears on information bits, we should use parity bit to recover missing part. Consider this formula:
bit0 + bit1 + bit2 = bit3
Examples from previous step:
0 + 1 + 0 = ? // result is 1, but it is not essential, since this is parity bit
? + 1 + 0 = 0 // expression is true only if ? = 1, so final bits are: 1100
1 + ? + 1 = 0 // expression is true for ? = 0, so result is: 1010
Take 3 bits of information and use them to formulate final message. Ignore parity bits, since they are only loss recovery strategy.
There may be surplus zero bits in last byte of message, added at encoding step - reduce them.