full code with comments