Sunday 9 December 2018

Final Post

Open Source was my first professional option course. I took it because

  • I heard from person working in the industry that open source knowledge/skill is important and that I must take this course
  • I heard from other students that this course is taught by a good professor
I am satisfied with this course. I learnt GitHub, gained some experience in open source, improved resume, and so on. Now I am going to try other courses. In the last year at Seneca I will definitely take second open source course.

Release 0.4 Week 3

This week I finished all PRs that were assigned to me last week:
Description of these functions can be found here
Third PR does not pass checks, because it uses function written in one of the previous PRs which was not merged yet.

Monday 3 December 2018

Release 0.4 Week 2

This week I chose issues in algorithms library I will work on next week and did a research about Math required to implement chosen algorithms. Of course, I am going to write efficient algorithms. These algorithms are:
Modular Multiplicative Inverse - function receives 2 integers a and m and returns smallest positive integer x such that
In simple words this means that ax - 1 is divisible by m
Modular Multiplicative Inverse using Fermets - the same problem but solved using Fermet's Small Theorem.
Fisher Yates - this is algorithm used to generate random permutations of a finite sequence.

Monday 26 November 2018

Release 0.4 Week 1

This week I was trying to find a project to work on. Small projects are usually too simple and small, so I can't contribute to them 3 or more times. Big projects look incomprehensible, I don't know how to start contributing to them. So, I decided to contribute to consumable algorithms library again. I booked 3 algorithms here.

Monday 19 November 2018

Release 0.3 Week 3


In release 0.3 I decided to focus on Seneca Blackboard Extension. I created 4 PRs 
and 5 issues (3 solved myself, 2 left for peers)
Before starting work on BB I thought it's very hard project because I had no idea how to do it. But after doing research I realized that Chrome extensions are easy: I even did not need to learn new material.
However, I faced 2 issues. The first issue was that BB developers did not properly specify ids and classes of elements, so it was often hard to access elements (and I did not manage to access some elements). The second issue was that peers also didn't follow same styling and writing principles. For example, all elements on BB have "h2" headers. Someone added Calendar with "caption" instead of "h2", so my code that changes "h2" styling didn't change Calendar header.

Monday 12 November 2018

Release 0.3 Week 2

This week I am working on Seneca Blackboard Extension.

First Contribution


I already created first pull request. In this PR I added icons of different sizes to our project and included them into manifest.json. Now icons are shown in extensions list, extensions settings, etc.


Current Tasks


I decided to reorganize and restyle Seneca Blackboard, because it looks old-fashioned and we remove old/insert new elements (issue-8).

When we change Seneca Blackboard code, bugs appear, so I decided to fix them.
Examples:
issue-51 issue-52

Monday 5 November 2018

Release 0.3 Week 1

Hacktoberfest has finished, so it's time to start looking for new projects, bugs, issues. We need to contribute to both "external" and "internal" projects. I haven't found any interesting "external" project yet, but I joined teams working on Seneca Blackboard and Student Centre Extensions for Google Chrome and Unity side-scrolling video game in C#.

Why did I choose these 2? It's pretty obvious that I decided to work on Seneca Services Extensions because Seneca Blackboard and Student Centre annoy most students (and probably professors). It's my chance to do a good deed and help a lot of students. We just created a repo for this project and have to start from the very beginning. This week I'm going to do a research to be able to start contributing to a project, as I need to understand how extensions work. Then I am going to create an initial extension (that just adds/removes and element).

Situation with Unity game is different. I just want to try working with Unity engine. This game already exists, but it's buggy. You can try it. It looks like one of the old 2D games on push-button phones. You can move left or right, jump, open doors to get to the next location, and solve puzzles (there is a lot of them). Again, I need to do a research, as I have never used Unity. Then I might create some new types of puzzles.


Wednesday 31 October 2018

Hacktoberfest Summary

Issues
Pull Requests
  1. pull-1
  2. pull-2 pull that resulted in pull-2
  3. pull-3
  4. pull-4
  5. pull-5
Posts
  1. post-1
  2. post-2
  3. post-3
  4. post-4
  5. post-5
This month I made 5 contributions to open source projects:
  1. 1 contribution to algorithms game
  2. 1 bug fix in filer
  3. 2 contributions to consumable algorithms library (biggest contributions)
  4. 1 contribution to a small guess number game
During October I learned in practice how to use GitHub, how to create pull requests, how to resolve conflicts in pull requests. That's, I learned how Open Source works.

I added 441 lines of code and removed 12 lines. Each pull request includes changes to code (no README spell checking, sorting, and so on).

What I like in Open Source


1. I can choose any project I like and work on it
2. Experienced programmers might help me

What I don't like in Open Source


1. It's hard to contribute to a big project because you have to learn a lot of code written in unfamiliar style (That's why I was happy to find consumable algorithms library. I didn't have to learn existing code, my code didn't interact with existing code)
2. In many projects (usually small projects) response time is a few weeks

I also was disappointed by the fact that most people are not trying to do something helpful, something that will really improve project. Instead, they just want to get a PR without coding.

Conclusion


In general, Hacktoberfest is a good idea: during October a lot of people contribute to open source projects, some of them might continue contributing after the end of Hacktoberfest. However, most people contribute with minor and often senseless changes and stop contributing after Hacktoberfest.

Next time in order to increase efficiency I will contribute a lot to one project instead of contributing to many projects.

Tuesday 30 October 2018

Hacktoberfest Fifth Pull Request

For my last pull request I again contributed to consumable algorithms library (yes, I like Math and algorithms). This time I chose Euler's Totient Function.
Euler's Totient Function counts the positive integers up to a given integer n that are relatively prime to n (relatively prime numbers are numbers that have only one common divisor - 1).

This is how Euler's function looks like:

The solution of the problem is reduced to one formula:
f(n) = (P1^B1 - P1^(B1 - 1))*(P2^B2 - P2^(B2 - 1)).....*(Pm^Bm - Pm^(Bm - 1)), where P are prime divisors of n and B are powers of divisors.

That's, to find f(n) we need

  • to find prime divisors of n and powers of divisors
  • to write fast power function
  • for fast power function we need to write Bitset class
You can see all code with JSDocs comments here.

Hacktoberfest Fourth Pull Request

For my fourth pull request I choose small project. It's a guess number game: user should guess a number in given range. When user types wrong number, he gets hints.
Try it

What I did

I tried playing this game and didn't like how "Show Hints" slider works. So, I decided to change it.
Before changes slider changed his state in the following case:

  • you clicked and released button inside slider
After changes:

  • you clicked inside slider and released button in the same coordinate
  • or you clicked inside slider, moved mouse to the correct side and released button
That's, for exampe, if slider is inactive, you click on it, move mouse to the left, and release button, slider will not change its state
Now, slider behaves like real slider (pull request is not merged yet)

This slider is using a Bootstrap class that defines its design and behaviour. The problem was that I did not want to change its design, so I did not remove a Bootstrap class. And because I didn't remove a Bootstrap class, I did not cancel its behaviour. That's, I had to write code "above that class" (default behaviour + my code = desired behaviour).

Links

Hacktoberfest Third Pull Request

This week I contributed to consumable algorithms library by creating the most complex and biggest pull request so far - Convex Hull function.

Convex Hull function


  • receives array of points with (x,y) coordinates
  • returns smallest sorted array of points that belong to smallest convex hull of received points
  • sorted array means that array[i] and array[i+1] are adjacent vertices of a hull (array[0] and array[array.length-1] are also adjacent
Here is an example of how this function should work:
Points connected by lines are points that are returned by function. As I already mentioned, returned array is sorted, so hull can be easily drawn (by drawing line segments connecting adjacent elements of returned array).

Here are more examples of how convexHull() works:
This is wrong:


This is correct:

Specific cases:

  • If function receives less than 3 points, it returns all points
  • If many points are on one line, only extreme points are returned

Implementation


To solve this problem I had to do a lot of Math and to write 8 functions. You can see full code with JSDocs comments  here. I also added tests for my code. If you want to use this function or any other function from algorithms library, check instructions here in README.md.

Monday 15 October 2018

Hacktoberfest Second Pull Request

In my second pull request I fixed a bug in Filer.

How I fixed a bug

  1. I was writing a test for rename() when oldPath==newPath (You can see a discussion here). It was expected that function will successfully rename a file, but it failed. We came to the conclusion that function implementation has a bug. Bug was assigned to me and I started working on it.
  2. I went to the implementation file, found rename() and tried to understand how it works.
  3. I found out that find_node() is called and went to it.
  4. In find_node() another function is called, in another function one more function is called, etc. There was a long way to find a mistake, a lot of functions was called. This long process is not interesting to read about, so I will not write about all ifs and function calls.
  5. Finally, check_if_new_file_exists() is called. It has this "if" inside:
if(_(newDirectoryData).has(newname)) { callback(new Errors.EEXIST('newpath resolves to an existing file', newname)); }
If a file with the name we want to rename a file to already exists, callback with an error is called. I removed this if statement and spaces in the else statement that is following this "if". After these changes my test with oldPath==newPath passed (all other tests also passed).

Fixing bugs in your own code is sometimes difficult, even though you know how your code works. But fixing bugs in someone else's code is always more difficult: you have to find out how it works. Different styling and programming techniques slow down debugging. So, I think it would be more rational if a person that wrote a code fixed bugs himself and other people just wrote tests.

Tuesday 9 October 2018

Hacktoberfest First Pull Request

I contributed to Hacktoberfest game. Here is the list of actions that must be done to take part in the game:

  •  I have asked for this issue, and was assigned it
  •  I have properly filled the "Details" section above arrow_up
  •  I didn't modify any test case red_circle
  •  I have implemented the function and all its tests pass white_check_mark
  •  I have added a new test case for someone to implement new
  •  I have created an issue for my new test case speak_no_evil
  •  I've star the repository (or not, all up to you)
  •  And more importantly, I've had fun! beer

To sum up, you need to solve a problem and to create a new problem that someone else will solve. The idea is that there are always available problems and everyone can start contributing to public repositories.

The Problem I solved

issue-527 pull-567

I wrote a function that takes unknown number of arguments and returns true if it contains any duplicate argument values. Otherwise, returns false (if all arguments are unique).

The algorithm is very simple:

  1. Go through the array of arguments for (let i=0; i<args.length;i++)
  2. For each argument go through the rest of the array for (let j=i+1; j<args.length;j++)
  3. If found the same argument, return true if (args[i] == args[j]) return true;
  4. If did not find any duplicates, return false return false;
Full code:

export const duplicatedArgs = (...args) => {
for (let i = 0; i < args.length; i++)
for (let j = i + 1; j < args.length; j++)
if (args[i] == args[j])
return true;
return false;
};

Problem I suggested

I suggested to write a power function. It is recommended that this function
works faster than O(n).
Here are tests for power():

describe('power', () => {
it('returns 125 for base 5 and power 3', () => {
expect(power(5, 3)).toEqual(125);
});

it('returns -125 for base -5 and power 3', () => {
expect(power(-5, 3)).toEqual(-125);
});

it('returns 1 for base 5 and power 0', () => {
expect(power(5, 0)).toEqual(1);
});

it('returns 5 for base 5 and power 1', () => {
expect(power(5, 1)).toEqual(5);
});

it('returns 1048576 for base 2 and power 20', () => {
expect(power(2, 20)).toEqual(1048576);
});
});

I recommend everyone to take part in this game, because it suits for your
first pull request on Hacktoberfest and it's not hard.
You can also use this game if you need help with some functions: just create
an issue with function description and someone will write it.😊

Friday 28 September 2018

Release 0.1

I have written a test for fs.rename() when oldPath=newPath.

  1. I started by looking at the list of fs methods in Node.js Documentation and found one (rename) that is clear to me.
  2. After forking filer to my account, I looked at the existing tests and found out that there is no tests for the case when oldPath=newPath.
  3. I wrote a test expecting that a path will be overwritten (as it is stated in Linux Programmer's Manual). By the way, Node.js Docs also state "in the case that newPath already exists, it will be overwritten.
  4. Unfortunately, my test failed. But after numerous experiments and attempts to fix the test, I came to the conclusion that this method might actually work differently.
  5. This is why I rewrote my test in a way that it expects failure in method execution. And it passed.
I still am not sure how rename() should work when oldPath=newPath, but it fails in this case. On the other hand, I learned how to create and run tests for Node.js modules.

Here is a final version of my test:

it('should fail to overwrite an existing file to itself', function (done) {
var fs = util.fs();

fs.open('/myfile', 'w+', function (error, fd) {
if (error) throw error;

fs.close(fd, function (error) {
if (error) throw error;
fs.rename('/myfile', '/myfile', function (error) {
expect(error).to.exist;
expect(error.code).to.equal('EEXIST');
done();
});
});
});
});

I created an issue stating that this test was missing: https://github.com/filerjs/filer/issues/493 and pull request with a test: https://github.com/filerjs/filer/pull/502

I also reveiwed peer's pull request: https://github.com/filerjs/filer/pull/539

describe('fsPromises.Write', function () {
it('should write, read a utf8 file without specifying utf8 in writeFile', function () {
//var fs = util.fs();
//var contents = 'This is a file.';
var fsPromises = util.fs().promises;
return fsPromises.writeFile('/myfile', { encoding: 'utf8' })
.then(() => {
return fsPromises.readFile('/myfile', 'utf8')
.catch((error) => {
expect(error).not.to.exist;
//expect(data).to.equal(contents);
//done();
});
});
});
});

After looking at this test, I went to existing tests and found out that this test already exists. Also, in return fsPromises.writeFile('/myfile' , { encoding: 'utf8' }) data parameter is missing.
I let pull request creator know about my comments.

Sunday 16 September 2018

fs.readFile() and fs.readFileSync()

Today I would like to discuss fs.readFile() and fs.readFileSync().

fs.readFile(path[, options], callback)

fs.readFile() is used to asynchronously read files. It takes up to 3 parameters:
path - can be string, Buffer, URL or integer. It specifies filename or file descriptor.
options - can be encoding string or null (example: 'utf8')
               or flag string (examples: 'a', 'as', 'w+'). Full list you can see here.
callback function takes 2 parameters:
Error err
and string or Buffer data that stores the contents of the file.

When you use this function, remember the following rules:

  • If you don't specify the encoding, the raw buffer is returned.
  • If you specify file descriptor, it has to include reading possibility.
  • This function buffers the entire file. If you care about memory, you might want to use another way of reading files.


Here is a sample code:

fs.readFile('demofile1.html'function(err, data) {
    res.writeHead(200, {'Content-Type''text/html'});
    res.write(data);
    res.end();
}


fs.readFileSync(path[, options])

fs.readFileSync() is used to synchronously read files. It takes up to 2 parameters:

path - can be string, Buffer, URL or integer. It specifies filename or file descriptor.
options - can be encoding string or null (example: 'utf8')
                           or flag string (examples: 'a', 'as', 'w+'). Full list you can see here.

Rules mentioned about fs.readFile() also apply to fs.readFileSync().

Here is a sample code:

fs.readFile('demofile1.html');

Sources:
https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback
https://nodejs.org/api/fs.html#fs_fs_readfilesync_path_options
https://www.w3schools.com/nodejs/nodejs_filesystem.asp