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.😊