Full Code of madlabsinc/teachcode for AI

next b97c7ba3cfbd cached
97 files
130.0 KB
34.9k tokens
9 symbols
1 requests
Download .txt
Repository: madlabsinc/teachcode
Branch: next
Commit: b97c7ba3cfbd
Files: 97
Total size: 130.0 KB

Directory structure:
gitextract_u8y5xtqs/

├── .eslintrc.js
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── custom.md
│   │   └── feature_request.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── config.yml
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── __e2e__/
│   ├── cli.test.js
│   ├── commands/
│   │   ├── fetchtask.test.js
│   │   ├── init.test.js
│   │   ├── showkeys.test.js
│   │   └── submit.test.js
│   └── helpers/
│       └── test-utils.js
├── bin/
│   └── index.js
├── commitlint.config.js
├── docs/
│   ├── .vuepress/
│   │   └── config.js
│   ├── README.md
│   └── guide/
│       ├── README.md
│       ├── commands.md
│       ├── contributing.md
│       └── installation.md
├── package.json
└── src/
    ├── commands/
    │   ├── init.js
    │   ├── keys.js
    │   ├── submit.js
    │   └── tasks.js
    ├── utils/
    │   ├── constants.js
    │   ├── github.js
    │   ├── logger.js
    │   └── validate.js
    └── workspace/
        ├── js/
        │   ├── solutions/
        │   │   ├── task1.js
        │   │   ├── task10.js
        │   │   ├── task11.js
        │   │   ├── task12.js
        │   │   ├── task13.js
        │   │   ├── task14.js
        │   │   ├── task15.js
        │   │   ├── task16.js
        │   │   ├── task17.js
        │   │   ├── task18.js
        │   │   ├── task19.js
        │   │   ├── task2.js
        │   │   ├── task20.js
        │   │   ├── task21.js
        │   │   ├── task22.js
        │   │   ├── task23.js
        │   │   ├── task24.js
        │   │   ├── task25.js
        │   │   ├── task26.js
        │   │   ├── task27.js
        │   │   ├── task28.js
        │   │   ├── task29.js
        │   │   ├── task3.js
        │   │   ├── task30.js
        │   │   ├── task4.js
        │   │   ├── task5.js
        │   │   ├── task6.js
        │   │   ├── task7.js
        │   │   ├── task8.js
        │   │   └── task9.js
        │   └── tasks.json
        └── python/
            ├── solutions/
            │   ├── task1.py
            │   ├── task10.py
            │   ├── task11.py
            │   ├── task12.py
            │   ├── task13.py
            │   ├── task14.py
            │   ├── task15.py
            │   ├── task16.py
            │   ├── task17.py
            │   ├── task18.py
            │   ├── task19.py
            │   ├── task2.py
            │   ├── task20.py
            │   ├── task21.py
            │   ├── task22.py
            │   ├── task23.py
            │   ├── task24.py
            │   ├── task25.py
            │   ├── task26.py
            │   ├── task27.py
            │   ├── task28.py
            │   ├── task29.py
            │   ├── task3.py
            │   ├── task30.py
            │   ├── task4.py
            │   ├── task5.py
            │   ├── task6.py
            │   ├── task7.py
            │   ├── task8.py
            │   └── task9.py
            └── tasks.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .eslintrc.js
================================================

module.exports = {
    extends: ['eslint:recommended', 'prettier'], // extending recommended config and config derived from eslint-config-prettier
    plugins: ['prettier'], // activating esling-plugin-prettier (--fix stuff)
    env: {
      "browser": true,
      "es6": true,
      "node": true
    },
    parserOptions: {
      sourceType: "module",
      ecmaVersion: "2018",
      allowImportExportEverywhere: false,
      ecmaFeatures: {
        globalReturn: false,
      }
    },
    rules: {
      "no-console": 0,
      'prettier/prettier': [ // customizing prettier rules (unfortunately not many of them are customizable)
        'error',
        {
          singleQuote: true,
          trailingComma: 'all',
        },
      ],
      eqeqeq: ['error', 'always'], // adding some custom ESLint rules
    },
  };


================================================
FILE: .github/FUNDING.yml
================================================
ko_fi: jamesgeorge007
patreon: jamesgeorge007
custom: https://www.paypal.me/jamesgeorge007


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
<!--Steps to reproduce the behavior:-->

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Environment Information**
<!-- Specify your local environment information such as the OS -->

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/custom.md
================================================
---
name: Custom issue template
about: Describe this issue template's purpose here.
title: ''
labels: ''
assignees: ''

---

## Do you want to request a feature or report a bug?

## What is the current behavior?
If the current behavior is a bug, please provide the steps to reproduce.

## What is the expected behavior?
If this is a feature request, what is motivation or use case for changing the behavior?

## Local Environment Information
Please paste the results of `teachcode info` here.

## Screenshots
If applicable, add screenshots to help explain your problem.

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: 'feat:'
labels: feature-request
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. -->

**What kind of change does this PR introduce?**
<!-- E.g. a bugfix, feature, refactoring, build related change, etc… -->

**Did you add tests for your changes?**

**If relevant, did you update the documentation?**

**Summary**

<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->
<!-- Try to link to an open issue for more information. -->

**Does this PR introduce a breaking change?**
<!-- If this PR introduces a breaking change, please describe the impact and a migration path for existing applications. -->

**Other information**

================================================
FILE: .github/config.yml
================================================
# ProBot Request Info (https://probot.github.io/apps/request-info/)

requestInfoReplyComment: >
  We would appreciate it if you could provide us with more info about this issue/pr!

requestInfoLabelToAdd: needs-more-info

# ProBot Welcome (https://probot.github.io/apps/welcome/)

newIssueWelcomeComment: >
  Thanks for opening your first issue here! Be sure to follow the issue template!

newPRWelcomeComment: >
  Thanks for opening this pull request! Please check out our contributing guidelines.

firstPRMergeComment: >
  ![congrats](https://media1.giphy.com/media/xT0xezQGU5xCDJuCPe/giphy.gif)

  Congrats on your very first contribution :clap: Looking forward to having more from your side


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
  push:
  pull_request:
    branches:
      - master
      - next
  workflow_dispatch:
jobs:
  job:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node: [16, 18, 20]
    steps:
      - uses: actions/checkout@v2
      - name: Setup node
        uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.node }}
          cache: 'npm'
      - name: Install packages
        run: npm ci
      - name: Run e2e tests
        run: npm run test

================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# VS-Code config
.vscode

# vuepress dist
docs/.vuepress/dist

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless

# FuseBox cache
.fusebox/


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
 advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
 address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
 professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at founders@madlabs.xyz. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq


================================================
FILE: LICENSE
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.


================================================
FILE: README.md
================================================
<p align="center">
  <a href="https://teachcode.madlabs.xyz/"><img src="https://i.imgur.com/BuMZB6C.png" width="240" height="240"></a>
  <h1 align="center">teachcode</h1>
  <p align="center"> A tool to develop and improve a student’s programming skills by introducing the earliest lessons of coding. </p>
</p>

<p align="center">
	<a href="https://travis-ci.com/madlabsinc/teachcode"><img src="https://travis-ci.com/madlabsinc/teachcode.svg?branch=master" alt="Build Status" /></a>
	<a href="https://www.npmjs.com/package/teach-code"><img src="https://badgen.net/npm/v/teach-code" alt="npm version" /></a>
	<a href="https://www.npmjs.com/package/teach-code"><img src="https://badgen.net/npm/dm/teach-code" alt="Downloads" /></a>
	<a href="https://github.com/madlabsinc/teachcode/pull/new"><img src="https://img.shields.io/badge/PRs%20-welcome-brightgreen.svg" alt="PRs Welcome" /></a>
	<a href="https://github.com/prettier/prettier"><img src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg" alt="code style: prettier" /></a>
	<a href="https://github.com/ulivz/awesome-vuepress"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome-VuePress" /></a>
	<a title="Chat on Telegram" href="https://t.me/teach_code"><img src="https://img.shields.io/badge/chat-Telegram-blueviolet?logo=Telegram"/></a>
	<a href="https://twitter.com/intent/follow?screen_name=teachcode_cli"><img src="https://img.shields.io/twitter/follow/teachcode_cli.svg?style=social&label=Follow%20@teachcode_cli" alt="Follow on Twitter"></a>
</p>

<p align="center">
	<a href='https://www.buymeacoffee.com/jamesgeorge007' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://bmc-cdn.nyc3.digitaloceanspaces.com/BMC-button-images/custom_images/orange_img.png' border='0' alt='Buy Me a Coffee' /></a>
</p>

---

**Chat: _[Telegram](https://t.me/teach_code)_**

**Donate: _[PayPal](https://www.paypal.me/jamesgeorge007), [Patreon](https://www.patreon.com/jamesgeorge007)_**

## Installation

`npm install -g teach-code`

## How to use

Users are required to solve 30 tasks that take them through the basic constructs of the programming language of their choice. The tasks are designed in such a way that the complexity increases as users progress through the tasks. One can't move forward until the current task is completed. Previously submitted tasks can be viewed if he/she wants but can't be worked on again.

- `teachcode` expects you to have a GitHub account. Make sure that you create one if you don't have one. [Learn more - Github Signup](https://docs.github.com/en/github/getting-started-with-github/signing-up-for-a-new-github-account)
- Navigate to the directory of your choice and type in `teachcode init`.
- Choose your track. Currently, we provide two tracks, Python and Javascript
- Enter your name. We ask for your name mainly for greeting purpose.
- Enter your GitHub username.
- Enter your GitHub personal token with repo access. [Learn more - GitHub Personal Token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token)
- Now type in `cd teachcode-solutions`.
- Type in `teachcode fetchtask`.
- Hurray :tada: you've got your first task.
- Type in your solution for the task in the file `task1.py` (opted learning track) using any code editor of choice. We recommend using [VS Code](https://code.visualstudio.com/)
- Now type in `teachcode submit` to submit your solution.
- Enter your Git credentials when prompted. [Learn more - Git Credentials](https://docs.github.com/en/github/getting-started-with-github/getting-started-with-git)
- Fetch the next task with `teachcode fetchtask`.

## Available Commands

| command                   | description                                                                           |
| ------------------------- | ------------------------------------------------------------------------------------- |
| teachcode init            | Initializes all the tasks                                                             |
| teachcode fetchtask [key] | Fetches the task correponding to the key if provided (defaults to the very next task) |
| teachcode submit          | Submits the current task                                                              |
| teachcode showkeys        | Lists all the keys associated with the submitted tasks                                |

## Contributing

Contributions of any kind are welcomed. Make sure that you go through these [guidelines](https://teachcode.madlabs.xyz/guide/contributing.html).

### How should I write a commit message?

This project uses [Commitlint](https://github.com/conventional-changelog/commitlint/#what-is-commitlint) to check if the commit messages meet the [conventional commit format](https://www.conventionalcommits.org/en/v1.0.0/).

The full pattern is:

```sh
type(scope?): subject #scope is optional

body? #body is optional

footer? #footer is optional
```

Following that pattern, your commit messages should look like these:

```sh
feat: activate open collective
```

```sh
chore: correct typo

It should be "guest" and not "gest"
```

```sh
refactor(cli): drop support for node 6

BREAKING CHANGE: you will need to update your node version to keep using this CLI
This closes #123
```

### How should I name my branches?

Prefix your branch names with `feat/`, `docs/` or `hotfix/` for feature proposals, documentation and bug fixes, respectively.

## License

Licensed under `GNU General Public License V3.0`.


================================================
FILE: __e2e__/cli.test.js
================================================
'use strict';

const test = require('ava');

const { run } = require('./helpers/test-utils');

test('supplying an unknown command errors', async t => {
  const { stderr } = await run(['create'], { reject: false });
  t.true(stderr.includes('Unknown command create'));
});


================================================
FILE: __e2e__/commands/fetchtask.test.js
================================================
'use strict';

const path = require('path');
const test = require('ava');
const fs = require('fs');

const { createUserConfig, run } = require('../helpers/test-utils');
const fileExtensionMap = require('../../src/utils/constants');

const workspacePath = path.join(__dirname, '..', '..', 'src', 'workspace');

// All files for testing purpose are generated within the teachcode-solutions directory
const workDir = path.join(__dirname, 'teachcode-solutions');

// Path to config.json
const configFilePath = path.join(workDir, 'config.json');

const learningTracks = Object.keys(fileExtensionMap);

// Create the teachcode-solutions directory
test.before(() => fs.mkdirSync(workDir));

// Cleanup
test.after(() => fs.rmdirSync(workDir, { recursive: true }));

test.serial('no config file in the current path should error', async t => {
  const { exitCode, stderr } = await run(['fetchtask'], {
    cwd: workDir,
    reject: false,
  });

  // Assertions
  // Exit code
  t.is(exitCode, 1);

  // Assert for the expected error message
  t.is(stderr.trim(), 'Could not find config.json in the current path!');
});

test.serial('supplying an invalid key should error', async t => {
  for (const track of learningTracks) {
    // Fetch the corresponding file extension
    const fileExtension = fileExtensionMap[track];

    // Create config.json
    const userConfig = createUserConfig(track, 6);
    fs.writeFileSync(configFilePath, JSON.stringify(userConfig, null, 2));

    const { exitCode, stderr, stdout } = await run(
      ['fetchtask', 'incorrectTestKey'],
      {
        cwd: workDir,
        reject: false,
      },
    );

    // Assertions
    // Exit code
    t.is(exitCode, 1);

    // The file shouldn't be created
    t.false(fs.existsSync(path.join(workDir, `task6.${fileExtension}`)));

    // Displays user name and progress information
    t.false(stdout.includes('User: testConfig'));
    t.false(stdout.includes('Progress: 6/30'));

    // Assert for the expected error message
    t.is(stderr.trim(), 'Make sure that you have grabbed the key correctly!');
  }
});

test.serial('should be able to access a completed task', async t => {
  for (const track of learningTracks) {
    // Fetch the corresponding file extension
    const fileExtension = fileExtensionMap[track];

    // Create config.json
    const userConfig = createUserConfig(track, 6);
    fs.writeFileSync(configFilePath, JSON.stringify(userConfig, null, 2));

    const { exitCode, stderr, stdout } = await run(['fetchtask', 'testKey2'], {
      cwd: workDir,
    });
    const tasksDir = track !== 'Python' ? fileExtension : track.toLowerCase();
    const tasks = require(path.join(workspacePath, tasksDir, 'tasks.json'));

    // Assertions
    // Exit code
    t.is(exitCode, 0);

    // The file shouldn't be created
    t.false(fs.existsSync(path.join(workDir, `task6.${fileExtension}`)));

    // Assert for the expected error message
    t.is(stderr.trim(), 'This task is already completed!');

    // Displays user name and progress information
    t.true(stdout.includes('User: testConfig'));
    t.true(stdout.includes('Progress: 6/30'));

    // Displays the second task
    t.true(stdout.includes(tasks[1].task));
  }
});

test.serial('access the current task with the respective key', async t => {
  for (const track of learningTracks) {
    // Fetch the corresponding file extension
    const fileExtension = fileExtensionMap[track];

    // Create config.json
    const userConfig = createUserConfig(track, 6);
    fs.writeFileSync(configFilePath, JSON.stringify(userConfig, null, 2));

    const { exitCode, stdout } = await run(['fetchtask', 'testKey6'], {
      cwd: workDir,
    });
    const tasksDir = track !== 'Python' ? fileExtension : track.toLowerCase();
    const tasks = require(path.join(workspacePath, tasksDir, 'tasks.json'));

    // Assertions
    // Exit code
    t.is(exitCode, 0);

    // Assert for the existence of the solution file
    t.true(fs.existsSync(path.join(workDir, `task6.${fileExtension}`)));

    // This message shouldn't be displayed
    t.false(stdout.trim().includes('This task is already completed'));

    // Displays user name and progress information
    t.true(stdout.includes('User: testConfig'));
    t.true(stdout.includes('Progress: 6/30'));

    // Displays the sixth task
    t.true(stdout.includes(tasks[5].task));
  }
});

test.serial('not supplying a key fetches the next task', async t => {
  for (const track of learningTracks) {
    // Fetch the corresponding file extension
    const fileExtension = fileExtensionMap[track];

    // Create config.json
    const userConfig = createUserConfig(track, 6);
    fs.writeFileSync(configFilePath, JSON.stringify(userConfig, null, 2));

    const { exitCode, stdout } = await run(['fetchtask'], { cwd: workDir });
    const tasksDir = track !== 'Python' ? fileExtension : track.toLowerCase();
    const tasks = require(path.join(workspacePath, tasksDir, 'tasks.json'));

    // Assertions
    // Exit code
    t.is(exitCode, 0);

    // Assert for the existence of the solution file
    t.true(fs.existsSync(path.join(workDir, `task6.${fileExtension}`)));

    // This message shouldn't be displayed
    t.false(stdout.trim().includes('This task is already completed'));

    // Displays user name and progress information
    t.true(stdout.includes('User: testConfig'));
    t.true(stdout.includes('Progress: 6/30'));

    // Displays the sixth task
    t.true(stdout.includes(tasks[5].task));
  }
});

test.serial(
  'displays an appropriate message if no more tasks are available',
  async t => {
    for (const track of learningTracks) {
      // Create config.json
      const userConfig = createUserConfig(track, 30);
      fs.writeFileSync(configFilePath, JSON.stringify(userConfig, null, 2));

      const { exitCode, stderr, stdout } = await run(['fetchtask'], {
        cwd: workDir,
      });

      // Assertions
      // Exit code
      t.is(exitCode, 0);

      // Won't display user name and progress information
      t.false(stdout.includes('User: testConfig'));
      t.false(stdout.includes('Progress'));

      // Assert for the expected message
      t.is(stderr.trim(), 'No more tasks available!');
    }
  },
);


================================================
FILE: __e2e__/commands/init.test.js
================================================
'use strict';

const path = require('path');
const test = require('ava');
const fs = require('fs');

const { createUserConfig, run } = require('../helpers/test-utils');

// All files for testing purpose are generated within the teachcode-solutions directory
const workDir = path.join(__dirname, 'teachcode-solutions');

// Path to config.json
const configFilePath = path.join(workDir, 'config.json');

// Create the teachcode-solutions directory
test.before(() => {
  fs.mkdirSync(workDir);
  const userConfig = createUserConfig('Python', 6);
  fs.writeFileSync(configFilePath, JSON.stringify(userConfig, null, 2));
});

// Cleanup
test.after(() => fs.rmdirSync(workDir, { recursive: true }));

test.serial(
  'displays an appropriate message if the teachcode-solutions directory exists in path',
  async t => {
    const { exitCode, stderr } = await run(['init'], {
      cwd: __dirname,
      reject: false,
    });

    // Assertions
    // Exit code
    t.is(exitCode, 1);

    // Assert for the expected error message
    t.true(
      stderr
        .trim()
        .includes(
          'It seems that there is already a teachcode-solutions directory or config.json file existing in path',
        ),
    );
  },
);

test.serial(
  'displays an appropriate message if the config.json file exists in path',
  async t => {
    const { exitCode, stderr } = await run(['init'], {
      cwd: workDir,
      reject: false,
    });

    // Assertions
    // Exit code
    t.is(exitCode, 1);

    // Assert for the expected error message
    t.true(
      stderr
        .trim()
        .includes(
          'It seems that there is already a teachcode-solutions directory or config.json file existing in path',
        ),
    );
  },
);


================================================
FILE: __e2e__/commands/showkeys.test.js
================================================
'use strict';

const path = require('path');
const test = require('ava');
const fs = require('fs');

const { run } = require('../helpers/test-utils');

const workDir = path.join(__dirname, 'teachcode-solutions');
const configFilePath = path.join(workDir, 'config.json');

// Create the teachcode-solutions directory
test.before(() => fs.mkdirSync(workDir));

// Cleanup
test.after(() => fs.rmdirSync(workDir, { recursive: true }));

// Execute tests serially as we are creating different temp config files for each test
test.serial('no config file in the current path should error', async t => {
  const { exitCode, stderr } = await run(['showkeys'], {
    cwd: workDir,
    reject: false,
  });

  // Assertions
  // Exit code
  t.is(exitCode, 1);

  // Assert for the expected error message
  t.is(stderr.trim(), 'Could not find config.json in the current path!');
});

test.serial(
  'shows up an appropriate message if the user is getting started',
  async t => {
    const configWithoutKeys = {
      userName: 'configWithoutKeys',
      taskCount: 0,
      keys: [],
    };

    // Create config.json
    fs.writeFileSync(
      configFilePath,
      JSON.stringify(configWithoutKeys, null, 2),
    );
    const { exitCode, stdout } = await run(['showkeys'], {
      cwd: workDir,
    });

    // Assertions
    // Exit code
    t.is(exitCode, 0);

    // Displays user name and progress information
    t.true(stdout.includes('User: configWithoutKeys'));
    t.true(stdout.includes('Progress: 1/30'));

    // Assert for the expected message
    t.true(
      stdout
        .trim()
        .includes(
          'Looks like this is your very first task. Type in teachcode fetchtask to get started!',
        ),
    );
  },
);

test.serial('displays the respective keys for the submitted tasks', async t => {
  const configWithMultipleKeys = {
    userName: 'configWithMultipleKeys',
    taskCount: 2,
    keys: ['testkey1', 'testkey2'],
  };

  // Create config.json
  fs.writeFileSync(
    configFilePath,
    JSON.stringify(configWithMultipleKeys, null, 2),
  );
  const { exitCode, stdout } = await run(['showkeys'], { cwd: workDir });

  // Assertions
  // Exit code
  t.is(exitCode, 0);

  // Displays completed tasks and the corresponding keys
  t.true(stdout.includes('Task-1: testkey1'));
  t.true(stdout.includes('Task-2: testkey2'));

  // Displays user name and progress information
  t.true(stdout.includes('User: configWithMultipleKeys'));
  t.true(stdout.includes('Progress: 3/30'));
});


================================================
FILE: __e2e__/commands/submit.test.js
================================================
'use strict';

const path = require('path');
const test = require('ava');
const fs = require('fs');

// const workspacePath = path.join(__dirname, '..', '..', 'src', 'workspace');

const { createUserConfig, run } = require('../helpers/test-utils');

// All files for testing purpose are generated within the teachcode-solutions directory
const workDir = path.join(__dirname, 'teachcode-solutions');

// Path to config.json
const configFilePath = path.join(workDir, 'config.json');

// Create the teachcode-solutions directory
test.before(() => fs.mkdirSync(workDir));

// Cleanup
test.after(() => fs.rmdirSync(workDir, { recursive: true }));

test.serial('no config file in the current path should error', async t => {
  const { exitCode, stderr } = await run(['submit'], {
    cwd: workDir,
    reject: false,
  });

  // Assertions
  // Exit code
  t.is(exitCode, 1);

  // Assert for the expected error message
  t.is(stderr.trim(), 'Could not find config.json in the current path!');
});

test.serial(
  'displays an appropriate message if the user is just starting out',
  async t => {
    // Create config.json
    const userConfig = createUserConfig('Python', 0, true);
    fs.writeFileSync(configFilePath, JSON.stringify(userConfig, null, 2));

    const { exitCode, stdout } = await run(['submit'], {
      cwd: workDir,
      reject: false,
    });

    // Assertions
    // Exit code
    t.is(exitCode, 0);

    // Assert for the expected error message
    t.true(
      stdout.includes(
        'Please use teachcode fetchtask to fetch your very first task',
      ),
    );
  },
);

test.serial(
  'displays an error message if an empty file is submitted',
  async t => {
    // Create config.json
    const userConfig = createUserConfig('Python', 6, true);
    fs.writeFileSync(configFilePath, JSON.stringify(userConfig, null, 2));

    const fileName = 'task6.py';
    fs.writeFileSync(path.join(workDir, fileName), '');

    const { exitCode, stderr } = await run(['submit'], {
      cwd: workDir,
      reject: false,
    });

    // Assertions
    // Exit code
    t.is(exitCode, 1);

    // Assert for the expected error message
    t.is(stderr.trim(), `The file ${fileName} is empty!`);
  },
);

test.serial(
  'displays an error message if the expected constructs are not used',
  async t => {
    // Create config.json
    const userConfig = createUserConfig('Python', 3, true);
    fs.writeFileSync(configFilePath, JSON.stringify(userConfig, null, 2));

    const fileName = 'task3.py';
    fs.writeFileSync(path.join(workDir, fileName), `print('HELLO WORLD')\n11`);

    const { exitCode, stderr } = await run(['submit'], {
      cwd: workDir,
      reject: false,
    });

    // Assertions
    // Exit code
    t.is(exitCode, 1);

    // Assert for the expected error message
    t.is(
      stderr.trim(),
      'Please make sure that you use the required constructs as provided',
    );
  },
);

test.serial(
  'displays an error message if there is an issue with the syntax for the submitted file',
  async t => {
    // Create config.json
    const userConfig = createUserConfig('Python', 3, true);
    fs.writeFileSync(configFilePath, JSON.stringify(userConfig, null, 2));

    const fileName = 'task3.py';
    fs.writeFileSync(path.join(workDir, fileName), `//`);

    const { exitCode, stderr } = await run(['submit'], {
      cwd: workDir,
      reject: false,
    });

    // Assertions
    // Exit code
    t.is(exitCode, 1);

    // Assert for the expected error message
    t.true(
      stderr.includes('Oops, there is something wrong with the syntax part!'),
    );
  },
);

test.serial(
  'displays an appropriate message if all the tasks are completed',
  async t => {
    // Create config.json
    const userConfig = createUserConfig('Python', 30, true);
    fs.writeFileSync(configFilePath, JSON.stringify(userConfig, null, 2));

    const { exitCode, stdout } = await run(['submit'], {
      cwd: workDir,
      reject: false,
    });

    // Assertions
    // Exit code
    t.is(exitCode, 0);

    // Assert for the expected error message
    t.true(stdout.trim().includes('All tasks are completed'));
  },
);


================================================
FILE: __e2e__/helpers/test-utils.js
================================================
const execa = require('execa');
const { join } = require('path');

const fileExtensionMap = require('../../src/utils/constants');

const CLI_PATH = join(__dirname, '..', '..', 'bin');

// Create config.json for testing purpose
const createUserConfig = (trackName, keysCount, isSubmit = false) => {
  const userConfig = {
    learningTrack: '',
    userName: 'testConfig',
    taskCount: 0,
    keys: [],
    userSubmittedFiles: [],
  };
  userConfig['learningTrack'] = trackName;

  // Early return to access the defaults
  if (keysCount === 0) {
    return userConfig;
  }

  // For the submit command the keys and submitted files count would be the same
  const filesCount =
    keysCount === 30 ? 30 : isSubmit ? keysCount : keysCount - 1;

  for (let i = 0; i < keysCount; i++) {
    userConfig['keys'].push(`testKey${i + 1}`);
  }
  for (let i = 0; i < filesCount; i++) {
    userConfig['userSubmittedFiles'].push(
      `task${i + 1}.${fileExtensionMap[trackName]}`,
    );
  }
  userConfig['taskCount'] = keysCount === 30 ? keysCount : keysCount - 1;

  return userConfig;
};

const run = (args, options) => execa('node', [CLI_PATH].concat(args), options);

module.exports = {
  createUserConfig,
  run,
};


================================================
FILE: bin/index.js
================================================
#!/usr/bin/env node

'use strict';

const chalk = require('chalk');
const program = require('commander');
const leven = require('leven');

const { version } = require('../package');

const logger = require('../src/utils/logger');

const initTasks = require('../src/commands/init');
const fetchTask = require('../src/commands/tasks');
const showKeys = require('../src/commands/keys');
const submitTask = require('../src/commands/submit');

// Defining all the available commands
program
  .name('teachcode')
  .version(version)
  .usage('<command> [options]');

program
  .command('init')
  .description('Initialize challenges')
  .action(initTasks);

program
  .command('submit')
  .description('Submits current task')
  .action(submitTask);

program
  .command('fetchtask [key]')
  .description('Fetch tasks to be worked upon')
  .action(fetchTask);

program
  .command('showkeys')
  .description('Shows keys of all the completed tasks')
  .action(showKeys);

const suggestCommands = cmd => {
  const availableCommands = program.commands.map(c => c._name);

  const suggestion = availableCommands.find(c => leven(c, cmd) < 3);
  if (suggestion) {
    logger.info(` Did you mean ${chalk.yellow(suggestion)}?`);
  }
};

// Validation for unknown commands
program.on('command:*', ([cmd]) => {
  program.outputHelp();
  console.log();
  logger.error(` Unknown command ${chalk.yellow(cmd)}.`);
  console.log();
  suggestCommands(cmd);
});

program.parse(process.argv);


================================================
FILE: commitlint.config.js
================================================
module.exports = {
  extends: ['@commitlint/config-conventional'],
};


================================================
FILE: docs/.vuepress/config.js
================================================

module.exports = {
    title: 'teachcode',
    description: 'Learn to code effectively',
    head: [
        ['link', { rel: 'icon', href: 'images/logo.png' }]
    ],
    themeConfig: {
    	repo: 'madlabsinc/teachcode',
        nav: [
            {text: 'Home', link: '/'},
            {text: 'Guide', link: '/guide/'},
        ],
        sidebar: {
            '/guide/': [{
                title: 'Guide',
                children: [
                  'installation',
                  'commands',
                  'contributing'
                ]
            }],
        },
        docsDir: 'docs',
        editLinks: true,
    	editLinkText: 'Edit this page on GitHub'
    }
}


================================================
FILE: docs/README.md
================================================
---
home: true
heroImage: images/teachcode.png
actionText: Get Started →
actionLink: /guide/
features:
- title: Learn Effectively
  details: Solve simple challenges in the end familiarising with a new programming language.
- title: Resume Anytime
  details: All completed tasks are pushed to a remote repository which makes it easier to track the user progress.
- title: Love The Terminal
  details: Everything happens in the CLI environment which inturn takes away the fear from novices.
footer: GPL V3 Licensed | Copyright © 2019-present MadHacks
---


================================================
FILE: docs/guide/README.md
================================================
# teachcode

> Brush up your programming skills right from the terminal.

## How it works

Users are required to solve 30 tasks that take them through the basic constructs of the programming language of their choice. The tasks are designed in such a way that the complexity increases as users progress through the tasks. One can't move forward until the current task is completed. Previously submitted tasks can be viewed if he/she wants but can't be worked on again.

- `teachcode` expects you to have a GitHub account. Make sure that you create one if that's not the case.
- Navigate to the directory of your choice and type in `teachcode init`. After typing the command, the following window would appear in your terminal

<br />

![image](https://user-images.githubusercontent.com/59525675/71776957-9b5c5500-2fbf-11ea-93fa-830f0842ac72.png)

<br />

- Select the language of your choice and follow the instructions as prompted.

<br />

![image](https://user-images.githubusercontent.com/43414928/71539868-c82dbe00-2968-11ea-997d-bb1e8ca01295.png)

<br />

- After entering your Github user token, you would get the following screen. Now type in `cd teachcode-solutions` followed by `teachcode fetchtask`.

<br />

- Hurray :tada: , you've got your first task.
- Now you can find a `config.json` and `task1.py` (language of choice) file within the `teachcode-solutions` directory.

<br />

![image](https://user-images.githubusercontent.com/59525675/71777696-458caa80-2fc9-11ea-9b07-89e6fc9f9432.png)

<br />

- Open up your favorite editor and code up the solution.

<br />

![image](https://user-images.githubusercontent.com/59525675/71777665-065e5980-2fc9-11ea-80d8-a4b34ad8657d.png)

<br />

- Now type in `teachcode submit`.
- Enter your Git credentials when prompted.
- If the current solution satisfies all test cases, you'll get the key to proceed farther.
- Now type in `teachcode fetchtask`.  
- Solve all 30 question, to complete the task 


*In case you want to revisit any of the previously submitted tasks, grab the associated key by typing in `teachcode showkeys` followed by `teachcode fetchtask <key>`*
- That's all folks, good luck :+1:





================================================
FILE: docs/guide/commands.md
================================================
---
title: 'Available Commands'
---

# Available Commands

 `teachcode` offers the following set of commands:-

 | command | description |                                                                                                
 | -------------- |  ---------------- |
 | teachcode init | Initializes all the tasks |
 | teachcode fetchtask \[key\] | Fetches the task correponding to the key if provided (Defaults to the very next task) |
 | teachcode submit | Submits the current task |
 | teachcode showkeys | Lists all the keys associated with the submitted tasks |

## Versioning And Help

| option | description
| --- | --- |
| -V, --version | Check CLI version |
| --help, -h | Get help and check usage |


================================================
FILE: docs/guide/contributing.md
================================================
---
title: 'Contributing'
---

# Contributing

## Guidelines

1. Fork and clone the repository.
2. Navigate to the project directory.
3. Now install the dependencies with `npm install`
4. Type in `npm link` which creates a symlink and thereby allowing `teachcode` to be accessed globally.
5. Make your life changing changes.
6. Ensure that your code is free from linting errors and is as per prettier conventions by typing in `npm run lint`.
7. We use [commitlint conventional naming rules](https://www.npmjs.com/package/@commitlint/config-conventional#rules) for our commits, make sure that you follow them.
8. Now you may push it to the remote repository by switching over to another branch and finally proposing a Pull Request to the base fork.


## Points to ponder

1. Make sure that you submit an issue first if you have something in mind that you're willing to work on.
2. Follow a `rebase` strategy to update your remote branch with the latest changes.
3. Prefix your branch names with `feat/`, `docs/` or `hotfix/` for feature proposals, docs-related and bug fixes, respectively.


================================================
FILE: docs/guide/installation.md
================================================
---
title: 'Installation'
---

# Installation

## Prerequisites

- [**npm**](https://www.npmjs.com/) is a package manager for the JavaScript programming language.
- [**node.js**](https://nodejs.org/en/) is an open-source, cross-platform JavaScript run-time environment that executes JavaScript code outside of a browser.
- [**git**](https://git-scm.com/) is a version control system for tracking changes in computer files and coordinating work on those files among multiple people. It is primarily used for source code management in software development.

## Quickstart

``` bash
npm install -g teach-code
teachcode init
```


================================================
FILE: package.json
================================================
{
  "name": "teach-code",
  "version": "1.3.2",
  "description": "A tool to develop and improve a student’s programming skills by introducing the earliest lessons of coding.",
  "main": "./bin/index.js",
  "files": [
    "bin",
    "src"
  ],
  "bin": {
    "teachcode": "./bin/index.js"
  },
  "scripts": {
    "lint": "eslint src bin __e2e__",
    "lint:fix": "eslint --fix src bin __e2e__",
    "pretest": "npm run lint",
    "test": "ava --serial",
    "docs:dev": "vuepress dev docs",
    "docs:build": "vuepress build docs"
  },
  "ava": {
    "files": [
      "__e2e__/**/*.test.js"
    ]
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  },
  "lint-staged": {
    "linters": {
      "src/**/*.js": "npm run lint"
    }
  },
  "keywords": [
    "node.js",
    "commander.js",
    "inquirer.js",
    "shell.js",
    "cli",
    "python3"
  ],
  "author": "James George <jamesgeorge998001@gmail.com>",
  "bugs": {
    "url": "https://github.com/madlabsinc/teach-code/issues"
  },
  "homepage": "https://github.com/madlabsinc/teach-code#readme",
  "license": "GPL-3.0",
  "dependencies": {
    "axios": "^0.21.1",
    "chalk": "^2.4.1",
    "commander": "^6.2.0",
    "execa": "^4.1.0",
    "inquirer": "^6.2.0",
    "leven": "^3.1.0",
    "node-banner": "^1.3.2",
    "open": "^7.0.0",
    "ora": "^4.0.3",
    "python-shell": "^1.0.7"
  },
  "devDependencies": {
    "@commitlint/cli": "^8.2.0",
    "@commitlint/config-conventional": "^8.2.0",
    "ava": "^3.13.0",
    "eslint": "^5.16.0",
    "eslint-config-prettier": "^4.3.0",
    "eslint-plugin-prettier": "^3.1.0",
    "husky": "^2.7.0",
    "lint-staged": "^8.1.7",
    "prettier": "^1.17.1",
    "vuepress": "^1.0.0"
  }
}


================================================
FILE: src/commands/init.js
================================================
'use strict';

const chalk = require('chalk');
const fs = require('fs');
const inquirer = require('inquirer');
const showBanner = require('node-banner');
const open = require('open');
const ora = require('ora');

const logger = require('../utils/logger');

// GitHub workflow helpers.
const {
  checkIfRepositoryExists,
  cloneRepository,
  createRepository,
  configureLocalRepo,
  initializeGHWorkFlow,
} = require('../utils/github');

const validate = require('../utils/validate');

// Key for the very first task
const key = '5e06b81de9ac43218a974785ffce8146';

let userConfig = {
  learningTrack: '',
  userName: '',
  taskCount: 0,
  keys: [],
  userSubmittedFiles: [],
};

/**
 * Displays the initial instructions
 *
 * @param {Boolean} kickStart - Identifies if the user is just starting out
 * @returns {Void}
 */

const showInstructions = () => {
  console.log();
  logger.success(' Perform the following steps:-');
  console.log();
  logger.info(' 1. cd teachcode-solutions');
  logger.info(` 2. teachcode fetchtask`);
};

/**
 * Opens up the default browser with information concerning
 * access token creation as required
 * @returns {Promise<void>}
 */

const promptAccessTokenCreation = async () => {
  const instructionsUrl =
    'https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line';

  console.log();
  logger.success(
    'You are required to have a personal access token for consuming the GitHub API.\nIf you do not have one, please follow these instructions.\n',
  );

  const { openInBrowser } = await inquirer.prompt([
    {
      name: 'openInBrowser',
      type: 'confirm',
      message: 'Open browser to read instructions?',
    },
  ]);
  if (openInBrowser) {
    // open link in the default browser
    await open(instructionsUrl);
  }
};

/**
 * Initialize all the tasks
 *
 * @returns {Promise<void>}
 */

const initTasks = async () => {
  await showBanner(
    'teachcode',
    ` Learn to code effectively ${`\t`.repeat(4)} Powered by MadHacks`,
  );
  console.log();

  if (
    ['./config.json', './teachcode-solutions'].some(path => fs.existsSync(path))
  ) {
    console.log();
    logger.error(
      `  It seems that there is already a ${chalk.yellow.bold(
        'teachcode-solutions',
      )} directory or ${chalk.yellow.bold(
        'config.json',
      )} file existing in path`,
    );
    process.exit(1);
  }

  console.log();
  logger.success(
    ` Welcome to teachcode${`\n`.repeat(2)}${`\t`.repeat(
      2,
    )} Points to ponder ${`\n`.repeat(
      4,
    )} 1. The files to submit the solutions are auto-created\n 2. Please pay attention to the desired output as specified in the task.\n 3. You have the provision to view previously submitted tasks ${`\n`.repeat(
      4,
    )}`,
  );

  // Prompt the user to choose between the available learning tracks
  const { learningTrackOfChoice } = await inquirer.prompt([
    {
      name: 'learningTrackOfChoice',
      type: 'list',
      message: 'Choose your track',
      choices: ['Python', 'JavaScript'],
    },
  ]);

  // Prompt the user asking for his/her name
  const { userName } = await inquirer.prompt([
    {
      name: 'userName',
      type: 'input',
      message: "What's your name:-",
      validate,
    },
  ]);

  // Setting up initial user-data config
  userConfig = {
    ...userConfig,
    learningTrack: learningTrackOfChoice,
    userName,
  };

  userConfig.keys.push(key);

  // Prompt for GitHub username.
  await initializeGHWorkFlow();

  // Check if the remote repository already exists.
  const shouldCreateRepository = await checkIfRepositoryExists();

  if (shouldCreateRepository) {
    await promptAccessTokenCreation();
    await createRepository();

    fs.mkdirSync('teachcode-solutions');
    fs.writeFileSync(
      'teachcode-solutions/config.json',
      JSON.stringify(userConfig, null, 2),
    );
    await configureLocalRepo();
  } else {
    const spinner = ora('Fetching user progress').start();
    try {
      // Clone the remote repository
      await cloneRepository();
    } catch (err) {
      spinner.fail('Something went wrong');
      throw err;
    }
    spinner.stop();
  }
  showInstructions();
};

module.exports = initTasks;


================================================
FILE: src/commands/keys.js
================================================
'use strict';

const chalk = require('chalk');
const fs = require('fs');
const showBanner = require('node-banner');

const logger = require('../utils/logger');

/**
 * Shows a list of keys that the user has hold of
 *
 * @returns {Promise<void>}
 */

const showKeys = async () => {
  await showBanner(
    'teachcode',
    ` Learn to code effectively ${`\t`.repeat(4)} Powered by MadHacks`,
  );
  console.log();

  if (!fs.existsSync(`./config.json`)) {
    logger.error(' Could not find config.json in the current path!');
    console.log();
    process.exit(1);
  }

  let userConfig = fs.readFileSync('./config.json', 'utf8');
  const { keys, userName, taskCount } = JSON.parse(userConfig);

  console.log();
  logger.success(
    `User: ${userName}${`\t`.repeat(6)}Progress: ${taskCount + 1}/30`,
  );

  if (keys.length === 0) {
    console.log();
    logger.info(
      `  Looks like this is your very first task. Type in ${chalk.yellow.bold(
        'teachcode fetchtask',
      )} to get started!`,
    );
    console.log();
  } else {
    keys.map((key, idx) => {
      console.log();
      logger.success(` Task-${idx + 1}: ${key}`);
    });
  }
};

module.exports = showKeys;


================================================
FILE: src/commands/submit.js
================================================
'use strict';

const chalk = require('chalk');
const { exec } = require('child_process');
const fs = require('fs');
const { PythonShell } = require('python-shell');
const showBanner = require('node-banner');
const path = require('path');

const fileExtensionMap = require('../utils/constants');
const logger = require('../utils/logger');
const { makeLocalCommit, pushToRemote } = require('../utils/github');

const keyStore = '123456789abcedefghijklmnopqrstuvwxyz';

let userConfig = {};

// Generate a random key that maps to a task
const generateKey = () => {
  let key = '';
  for (let i = 0; i < 36; i++) {
    key += keyStore.charAt(Math.floor(Math.random() * keyStore.length));
  }
  return key;
};

// Keywords for validating solutions
const validationKeys = [
  'len',
  '/3',
  'if',
  'for',
  'while',
  'for',
  'if',
  '/3',
  '/2',
  'strip',
  ':',
  ':',
  'def',
  'if',
  'return',
  'asctime',
  'math.sqrt',
  '[',
  '[',
  'append',
  'else',
  '{',
  'except',
  'return',
  'range',
  'for',
  '%',
  '[::',
];

/**
 * Compares the user submitted solution (result) with that of the predefined version
 *
 * @param {String} submittedFileContent - Content of the user submitted file
 * @param {String} solutionFileContent - Predefined solution file content
 * @param {Number} totalTasks - Total number of tasks for the respective learning track
 *
 * @returns {Promise<void>}
 */

const checkSolution = async (
  submittedFileContent,
  solutionFileContent,
  totalTasks,
) => {
  let { learningTrack, taskCount, keys } = userConfig;
  try {
    if (submittedFileContent.toString() === solutionFileContent.toString()) {
      if (taskCount === totalTasks) {
        logger.info(' Info: No more tasks are available!');
        process.exit(0);
      }

      // Updating config.json information.
      taskCount++;

      // Push a randomly generated key to the keys array
      keys.push(generateKey());

      userConfig = {
        ...userConfig,
        taskCount: Math.min(taskCount, totalTasks),
        keys,
      };

      // Write back the updated config
      fs.writeFileSync('./config.json', JSON.stringify(userConfig, null, 2));

      await makeLocalCommit(taskCount);

      // User is prompted for credentials unless they are valid
      do {
        try {
          await pushToRemote();
          break;
        } catch (err) {
          logger.error('Error: Invalid credentials');
        }
      } while (true); // eslint-disable-line

      // Successfully completed the task
      console.log();
      logger.success(` Hurray you've done it!`);
      console.log();

      // All tasks are completed
      if (taskCount === totalTasks) {
        logger.info(' Info: No more tasks are available!');
        process.exit(0);
      }

      logger.success(
        `Move to the next task with ${chalk.yellow.bold(
          'teachcode fetchtask',
        )}`,
      );
    } else {
      console.log();
      logger.warn(
        ` The solution doesn't meet all the output requirements. Please have a look again!`,
      );
      console.log();
    }
  } catch (err) {
    console.log();
    logger.error(
      ` There is something wrong with task${taskCount + 1}.${
        fileExtensionMap[learningTrack]
      }`,
    );
  }
};

/**
 * Validates if the solution meets all the criteria
 *
 * @param {any} solutionFile - User submitted file
 * @returns {Void}
 */

const validateSolution = solutionFile => {
  const fileContent = fs.readFileSync(solutionFile, 'utf8').toString();
  const { learningTrack, taskCount } = userConfig;

  // Validation for the submitted solution
  if (learningTrack === 'Python') {
    if (taskCount >= 2) {
      if (!fileContent.includes(validationKeys[taskCount - 2])) {
        console.log();
        logger.error(
          ' Please make sure that you use the required constructs as provided',
        );
        process.exit(1);
      }
    }
  } else {
    // TODO: Validation for JS solutions
  }
};

/**
 * Solution submission logic
 *
 * @returns {Void}
 */

const submitTask = async () => {
  await showBanner(
    'teachcode',
    ` Learn to code effectively ${`\t`.repeat(4)} Powered by MadHacks`,
  );
  console.log();

  if (!fs.existsSync('./config.json')) {
    logger.error(' Could not find config.json in the current path!');
    console.log();
    process.exit(1);
  }

  // Read from config.json
  userConfig = JSON.parse(fs.readFileSync('./config.json', 'utf8'));
  const { userName, userSubmittedFiles, learningTrack, taskCount } = userConfig;

  const fileExtension = fileExtensionMap[learningTrack];
  const tasksDir = learningTrack === 'Python' ? 'python' : fileExtension;

  // Path to the tasks and their solutions
  const workSpacePath = path.join(__dirname, '..', 'workspace', tasksDir);
  const exercises = require(path.join(workSpacePath, 'tasks'));

  const solutionFile = path.join(
    workSpacePath,
    'solutions',
    `task${taskCount + 1}.${fileExtension}`,
  );

  if (taskCount !== exercises.length) {
    console.log();
    const progressInfo = `${taskCount + 1}/${exercises.length}`;
    logger.success(
      `User: ${userName}${`\t`.repeat(6)}Progress: ${progressInfo}`,
    );
  } else {
    console.log();

    logger.success(` Congrats ${userName} you've made it through!`);
    console.log();

    logger.success(' All tasks are completed!');
    console.log();
    process.exit(0);
  }

  if (!userSubmittedFiles.length) {
    console.log();
    logger.info(
      ` Please use ${chalk.yellow.bold(
        'teachcode fetchtask',
      )} to fetch your very first task`,
    );
    process.exit(0);
  }

  if (taskCount === userSubmittedFiles.length) {
    console.log();
    logger.info(' Info: Task already submitted!');
    console.log();
    process.exit(0);
  }

  const submittedFile = userSubmittedFiles.slice(-1).pop();
  const submittedFileContent = fs
    .readFileSync(submittedFile, 'utf8')
    .toString()
    .split('');

  if (!submittedFileContent.length) {
    console.log();
    logger.error(` The file task${taskCount + 1}.${fileExtension} is empty!`);
    console.log();
    process.exit(1);
  }

  if (learningTrack === 'Python') {
    PythonShell.run(submittedFile, null, (err, result) => {
      if (err) {
        console.log();
        logger.error(' Oops, there is something wrong with the syntax part!');
        console.log();
        logger.error(err.toString());
        process.exit(1);
      }

      PythonShell.run(solutionFile, null, (err, solution) => {
        if (err) {
          logger.error(' ' + err.toString());
          process.exit(1);
        }

        if (typeof result === 'undefined' || typeof solution === 'undefined') {
          console.log();
          logger.error(
            ` Please take a look at task${taskCount}.${fileExtension}`,
          );
          process.exit(1);
        }
        validateSolution(submittedFile);
        checkSolution(result, solution, exercises.length);
      });
    });
  } else {
    exec(`node ${submittedFile}`, (err, result) => {
      if (err) {
        logger.error(' Oops there is something wrong with the syntax part!');
        process.exit(1);
      }
      exec(`node ${solutionFile}`, (err, solution) => {
        if (err) throw err;
        validateSolution(submittedFile);
        checkSolution(result, solution, exercises.length);
      });
    });
  }
};

module.exports = submitTask;


================================================
FILE: src/commands/tasks.js
================================================
'use strict';

const fs = require('fs');
const path = require('path');
const showBanner = require('node-banner');

const fileExtensionMap = require('../utils/constants');
const logger = require('../utils/logger');

/**
 * Fetch the respective task corresponding to the supplied key
 *
 * @param {String} key - key that corresponds to a task
 * @returns {Promise<void>}
 */

const fetchTask = async key => {
  await showBanner(
    'teachcode',
    ` Learn to code effectively ${`\t`.repeat(4)} Powered by MadHacks`,
  );
  console.log();

  if (!fs.existsSync('./config.json')) {
    logger.error(' Could not find config.json in the current path!');
    console.log();
    logger.info(
      ' Make sure that you are within the teachcode-solutions directory!',
    );
    console.log();
    process.exit(1);
  }

  // Reading the user-config information.
  const userConfig = JSON.parse(fs.readFileSync('./config.json', 'utf8'));

  const {
    learningTrack,
    userName,
    taskCount,
    keys,
    userSubmittedFiles,
  } = userConfig;

  // For eg: task1.py
  const fileName = `task${taskCount + 1}.${fileExtensionMap[learningTrack]}`;

  const tasksDir =
    learningTrack === 'Python' ? 'python' : fileExtensionMap[learningTrack];
  const exercises = require(path.join(
    __dirname,
    '..',
    'workspace',
    tasksDir,
    'tasks',
  ));

  // Progress information
  const progressInfo = `${Math.min(taskCount + 1, 30)}/${exercises.length}`;

  if (key && !keys.includes(key)) {
    console.log();
    logger.error('Make sure that you have grabbed the key correctly!');
    console.log();
    process.exit(1);
  }

  // Check if no more tasks are available (no key provided)
  if (!key && taskCount === exercises.length) {
    console.log();
    logger.warn(' No more tasks available!');
    process.exit(0);
  }

  // In case no key is provided, fetch the next task
  if (!key) {
    key = keys.slice(-1).pop();
  }

  // Fetch the key position within the user config if it is not the current task
  const taskIdx = keys.slice(0, taskCount).indexOf(key);

  if (taskIdx !== -1) {
    console.log();
    logger.warn(' This task is already completed!');

    console.log();
    console.log();

    // Display user name and progress information
    logger.success(
      `User: ${userName}${`\t`.repeat(4)}Progress: ${progressInfo}`,
    );
    console.log();

    // Display the task corresponding to the key supplied
    logger.success(exercises[taskIdx].task);
    console.log();
    return;
  }

  // Grab the key corresponding to the most recent task
  if (keys.slice(-1).pop() === key) {
    if (!userSubmittedFiles.includes(fileName)) {
      userSubmittedFiles.push(fileName);
    }

    // Write back the updated config
    fs.writeFileSync('./config.json', JSON.stringify(userConfig, null, 2));

    // Display user name and progress information
    console.log();
    logger.success(
      `User: ${userName}${`\t`.repeat(6)}Progress: ${progressInfo}`,
    );

    // Display the task
    console.log();
    logger.success(exercises[taskCount].task);
    console.log();

    // Create a file to submit the solution corresponding to the current task
    const commentChar = learningTrack === 'Python' ? '#' : '//';
    fs.writeFileSync(
      fileName,
      `${commentChar} Write your solution in this file`,
    );
  }
};

module.exports = fetchTask;


================================================
FILE: src/utils/constants.js
================================================
'use strict';

// Holds a reference to the file extensions corresponding to the learning track
const fileExtensionMap = {
  Python: 'py',
  JavaScript: 'js',
};

module.exports = fileExtensionMap;


================================================
FILE: src/utils/github.js
================================================
'use strict';

const axios = require('axios');
const chalk = require('chalk');
const execa = require('execa');
const inquirer = require('inquirer');

const validate = require('./validate');

// Global reference to the GitHub username.
let GHUserName;

/**
 * Initial Git workflow
 *
 * @returns {Promise<void>}
 */

const initializeGHWorkFlow = async () => {
  const { userName } = await inquirer.prompt({
    name: 'userName',
    message: 'GitHub username:-',
    type: 'input',
    validate,
  });

  // Holding global reference to the GitHub username.
  GHUserName = userName;

  // Check if it is a valid username
  if (!(await checkIfValidUser())) {
    console.log();
    console.log(chalk.red.bold(` ${userName} isn't a valid GitHub username`));
    console.log();
    await initializeGHWorkFlow();
  }
};

/**
 * Checks if the remote repository exists
 *
 * @returns {Promise<boolean>}
 */

const checkIfValidUser = async () => {
  const API_URL = `https://api.github.com/users/${GHUserName}`;
  try {
    await axios.get(API_URL);
    return true;
  } catch (err) {
    return false;
  }
};

/**
 * Checks if the remote repository exists
 *
 * @returns {Promise<boolean>}
 */

const checkIfRepositoryExists = async () => {
  const API_URL = `https://api.github.com/repos/${GHUserName}/teachcode-solutions`;

  // Checking whether the remote repository exists.
  try {
    await axios.get(API_URL);
    return false;
  } catch (err) {
    // Repository should be created.
    return true;
  }
};

/**
 * Clone a remote repository to the local machine
 *
 * @returns {Promise<void>}
 */

const cloneRepository = async () => {
  const repoUrl = `https://github.com/${GHUserName}/teachcode-solutions`;
  await execa.command(`git clone ${repoUrl}`);
};

/**
 * Create a remote repository
 *
 * @returns {Promise<void>}
 */

const createRepository = async () => {
  const { userToken } = await inquirer.prompt({
    name: 'userToken',
    message: 'GitHub user token:-',
    type: 'password',
    validate,
  });

  const API_URL = `https://api.github.com/user/repos`;
  axios.defaults.headers.common['Authorization'] = `token ${userToken}`;
  // Create a new repository.
  try {
    await axios.post(API_URL, { name: 'teachcode-solutions' });
  } catch (err) {
    console.log(chalk.red.bold('Error: Invalid credentials'));
    console.log();
    await createRepository();
  }
};
/**
 * Configure local repository
 *
 * @returns {Promise<void>}
 */

const configureLocalRepo = async () => {
  const repoUrl = `https://github.com/${GHUserName}/teachcode-solutions`;

  // Initialize an empty git repo.
  await execa.command('git init', { cwd: 'teachcode-solutions' });

  // Set the remote url.
  await execa.command(`git remote add origin ${repoUrl}`, {
    cwd: 'teachcode-solutions',
  });
};

/**
 * Creates a local commit on each submission
 *
 * @param {Number} taskCount - Holds the present task count
 * @returns {Promise<void>}
 */

const makeLocalCommit = async taskCount => {
  await execa.command('git add .');
  await execa.command(`git commit -m "solution for task-${taskCount}"`);
};

/**
 * Push to the remote repository once the current task was successfully completed
 *
 * @returns {Promise<void>}
 */

const pushToRemote = async () => {
  console.log();
  await execa.command('git push origin master', { stdio: 'inherit' });
};

module.exports = {
  checkIfRepositoryExists,
  cloneRepository,
  configureLocalRepo,
  createRepository,
  initializeGHWorkFlow,
  makeLocalCommit,
  pushToRemote,
};


================================================
FILE: src/utils/logger.js
================================================
'use strict';

const chalk = require('chalk');

const error = msg => console.error(chalk.red.bold(msg));

const info = msg => console.info(chalk.cyan.bold(msg));

const success = msg => console.log(chalk.green.bold(msg));

const warn = msg => console.warn(chalk.yellow.bold(msg));

module.exports = {
  error,
  info,
  success,
  warn,
};


================================================
FILE: src/utils/validate.js
================================================
'use strict';

/**
 * Validate user input
 *
 * @param {String} userInput
 * @returns {Boolean}
 */

const validateInput = userInput => {
  if (!userInput) {
    console.log('This field is required!');
    return false;
  }
  return true;
};

module.exports = validateInput;


================================================
FILE: src/workspace/js/solutions/task1.js
================================================
console.log('Hello World');


================================================
FILE: src/workspace/js/solutions/task10.js
================================================
let s = 1;
do {
  if (s % 2 === 0) {
    console.log(s + ' is even.');
  } else {
    console.log(s + ' is odd.');
  }
  s++;
} while (s <= 20);


================================================
FILE: src/workspace/js/solutions/task11.js
================================================
let i = 1;
while (i <= 15) {
  if (i % 3 === 0) {
    i++;
    continue;
  } else if (i === 13) {
    break;
  } else {
    console.log(i);
  }
  i++;
}


================================================
FILE: src/workspace/js/solutions/task12.js
================================================
let no = [45, 23, 767, 921];

for (let i = 0; i < no.length; i++) {
  if (no[i] > 23) console.log(no[i]);
}


================================================
FILE: src/workspace/js/solutions/task13.js
================================================
let a = ['ABC', 'GHI', 'DEF', 'JKL'];
let b = [1, 2, 3];
a.pop();
console.log(a);
a.push('PQR');
console.log(a);
a.shift();
console.log(a);
a.splice(1, 2, 'WER', 'ERT');
console.log(a);
a = a.concat(b);
console.log(a);
a.sort();
console.log(a);
a.reverse();
console.log(a);
let c = b.map(element => {
  return 2 * element;
});
console.log(c);


================================================
FILE: src/workspace/js/solutions/task14.js
================================================
function add(a, b) {
  console.log(a + b);
}
add(1, 2);
add(10, 15);
add(100, 400);


================================================
FILE: src/workspace/js/solutions/task15.js
================================================
let person = {
  age: 75,
  gender: 'female',
};

let yyyy = 2019 - person.age;
console.log(yyyy);
console.log(person.gender);


================================================
FILE: src/workspace/js/solutions/task16.js
================================================
console.log(Math.round(5.57));
console.log(Math.pow(6, 3));
console.log(Math.sqrt(841));
console.log(Math.ceil(5.3));
console.log(Math.floor(5.3));


================================================
FILE: src/workspace/js/solutions/task17.js
================================================
let day;
switch (new Date().getDay()) {
  case 0:
    day = 'Sunday';
    break;
  case 1:
    day = 'Monday';
    break;
  case 2:
    day = 'Tuesday';
    break;
  case 3:
    day = 'Wednesday';
    break;
  case 4:
    day = 'Thursday';
    break;
  case 5:
    day = 'Friday';
    break;
  case 6:
    day = 'Saturday';
}
console.log(day);


================================================
FILE: src/workspace/js/solutions/task18.js
================================================
let a = true.toString();
let b = false.toString();
console.log(typeof a);
console.log(typeof b);
let c = true;
let d = false;
console.log(typeof c);
console.log(typeof d);


================================================
FILE: src/workspace/js/solutions/task19.js
================================================
let a = 10;
function abc() {
  let a = 4;
  console.log(a);
}

abc();
console.log(a);


================================================
FILE: src/workspace/js/solutions/task2.js
================================================
const str = 18;
console.log(str);


================================================
FILE: src/workspace/js/solutions/task20.js
================================================
const pounds = [11.21, 19.21, 46.21];

const sum = pounds.reduce((total, amount) => total + amount);

console.log(sum);


================================================
FILE: src/workspace/js/solutions/task21.js
================================================
const numbers = [1, 3, 4, 6, 8, 9];

const filterValues = () => {
  return numbers.filter(number => {
    return number % 2 === 0;
  });
};

console.log(filterValues());


================================================
FILE: src/workspace/js/solutions/task22.js
================================================
let a = [3, 9, 12, 15, 18];
console.log(a.indexOf(15, 2));
console.log(a.indexOf(14, 1));


================================================
FILE: src/workspace/js/solutions/task23.js
================================================
let obj = {
  name: 'ABC',
  education: 'CSE',
};
console.log(Object.keys(obj));
let arr = ['A', 'B', 'C'];
console.log(Object.keys(arr));


================================================
FILE: src/workspace/js/solutions/task24.js
================================================
let text = '{ "name":"John", "age":"39", "city":"New York"}';
let obj = JSON.parse(text, function(key, value) {
  if (key === 'city') {
    return value.toUpperCase();
  } else {
    return value;
  }
});

console.log(obj);


================================================
FILE: src/workspace/js/solutions/task25.js
================================================
console.log(JSON.stringify({ x: 5, y: 6 }));


================================================
FILE: src/workspace/js/solutions/task26.js
================================================
let goals = ['Mission', 'Vision', 'Dedication'];
console.log(goals.includes('Mission'));
console.log(goals.includes('Success'));


================================================
FILE: src/workspace/js/solutions/task27.js
================================================
const array1 = ['abc', 'bcd', 'cde'];

array1.forEach(item => console.log(item));
for (const element of array1) {
  console.log(element);
}
for (const index in array1) {
  console.log(index);
}


================================================
FILE: src/workspace/js/solutions/task28.js
================================================
let str = 'JS is AWESOME!';
let arr = str.split(' ');
console.log(arr);
let a = ['I', 'love', 'JS!'];
let s = a.join(' ');
console.log(s);


================================================
FILE: src/workspace/js/solutions/task29.js
================================================
let str = 'Hello, I am a novice JS Developer.';
console.log(str.startsWith('Hello'));
console.log(str.endsWith('Develop'));
let str1 = 'I am a Polyglot';
console.log(str1.substr(str1.indexOf('P'), str1.indexOf('t')));
console.log(str1.substring(str1.indexOf('a'), str1.indexOf('t') + 1));


================================================
FILE: src/workspace/js/solutions/task3.js
================================================
const str = 'JS is cool!';
console.log(str);


================================================
FILE: src/workspace/js/solutions/task30.js
================================================
let counter = 0;

const startCounter = () => {
  counter++;
  process.stdout.write(`${counter} `);
};

const interval = setInterval(startCounter, 1000);

setTimeout(() => clearInterval(interval), 6000);


================================================
FILE: src/workspace/js/solutions/task4.js
================================================
const str = ' Hey, this is Task 4 of JS Path! ';
console.log(str.length);
console.log(str.indexOf('Task'));
console.log(str.slice(24, 26));
let str1 = str.replace('JS', 'Python');
console.log(str1);
str1 = str1.concat('!');
console.log(str1);
console.log(str1.trim());


================================================
FILE: src/workspace/js/solutions/task5.js
================================================
const a = 25;
const b = 33;
console.log(a + b);
console.log(a - b);
console.log(a * b);
console.log(a / b);
console.log(a % b);
console.log(a ** 2);


================================================
FILE: src/workspace/js/solutions/task6.js
================================================
const a = 44;
const b = 29;
// eslint-disable-next-line eqeqeq
console.log(a == b);
console.log(a === b);
console.log(a !== b);
console.log(a > b);
console.log(a < b);
console.log(a >= b);
console.log(a <= b);


================================================
FILE: src/workspace/js/solutions/task7.js
================================================
const a = 34;
const b = 23;
const c = 1;
console.log(a > b && a < c);
console.log(a < b || a > c);
console.log(!(b < a));


================================================
FILE: src/workspace/js/solutions/task8.js
================================================
for (let i = 1; i <= 12; i++) {
  if (i % 4 === 0) {
    console.log(i);
  }
}


================================================
FILE: src/workspace/js/solutions/task9.js
================================================
let x = 1;
while (x <= 50) {
  if (x % 5 === 0) {
    console.log('Buzz');
  } else {
    console.log(x);
  }
  x++;
}


================================================
FILE: src/workspace/js/tasks.json
================================================
[
  {
    "task": "Hey there folks, you have chosen JS Path! \n Here's your first task! All the best...\n Task 1:-\n Print Hello World to the console"
  },
  {
    "task": "Great! Now's let's move on to variables. Variables are used to store data values \n Task 2:-\n Declare a variable to store the value 18 and print the value."
  },
  {
    "task": "Let's move on to strings. Strings represent a set of characters written within quotes. \n Task 3:-\n Declare a variable to store the value 'JS is cool!' and print it."
  },
  {
    "task": "Keep it up! Let's move on to String methods. There are a variety of methods for string manipulation in JS. Some of them are: \n 1. length - To find the length of the string. \n 2. indexOf() - Returns the first occurence of a specified text in a string. \n 3. slice() - extracts a part of a string and returns the extracted part. \n 4. replace() - replaces a specified value with another value in a string. \n 5. concat() - to join two or more strings. \n 6. trim() - removes the white space from both sides of the string. \n Task 4:-\n Obtain the following output for the string ' Hey, this is Task 4 of JS Path! ' \n Output: \n Length of the string \n Display the index of first occurence of 'Task' \n Slice the string for displaying 'JS' \n Replace JS with Python \n Concatenate '!' to the end of the string. \n Remove the whitespaces from the beginning and end of the string."
  },
  {
    "task": "Impressive! Let's move on to the next topic:  Operators. \n There are a variety of operators. Let's move on to Arithmetic Operators: +,-,*,/,%, **. \n Here's your task:\n Task 5:- \n Take 25 & 33 as your operands and print their sum, difference, product, quotient, remainder, 25^2."
  },
  {
    "task": "Awesome! Let's move on to Comparison Operators. They are used to compare two values. They return true or false according to the value of their operands. They are: ==, ===, !=, >, <, >=, <=. Here's your task:\n Task 6:-\n Use 44 & 29 as your operands. Compare them using the Comparison operators in the same order and print the value which they return."
  },
  {
    "task": "Now, let's move on to Logical Operators. They too return true or false according to the value of their operands. They are : \n && - returns true if both operands are true \n || - returns true if any of the operands are true \n ! - negates whatever the statement inside is. \n Here's your task: \n Task 7:- \n Use 34,23,1 as your operands. Check whether\n 1. 34>23 and 34<1 \n 2. 34<23 or 34>1 \n 3. not 23<34"
  },
  {
    "task": "Great! Let's move on to Loops now. Loops are used to repeat the same code without writing it over and over again. \n Let's start with for loop. Syntax: \n for (initialization; condition; update)\n{// code block to be executed} \n Here's your task: \n Task 8:- \n Print the multiples of 4 from 1 to 12 using for loop."
  },
  {
    "task": "Let's move on to another loop, the while loop, along with the if-else blocks. while loop is also an entry controlled loop, i.e, it checks the condition first before it starts executing. If-else blocks are used to compare the values and execute according to the conditions given. \n Syntax: \n while(condition) \n {block of statements; update statement;} \n Here's your task: \n Task 9:- \n Print the numbers from 1 to 50. Print Buzz if the number is a multiple of 5."
  },
  {
    "task": "Great work! Let's move on to another loop, the do while loop. Unlike other loops, this one is an exit controlled loop, i.e, it executes at least once. It checks the condition only at the exit. \n Syntax: do{\n loop block\n}(while(condition)); \n Here's your task: \nTask 10:-\n Iterate through the numbers 1 to 20 and print whether the number is odd or even. \n Here's the sample output: \n 1 is odd. \n2 is even. ....\n20 is even."
  },
  {
    "task": "Awesome! Let's now move on to break and continue statements. \n break statement is used to break out of the loop when required. It stops the iteration when used in loops. \n continue statments are used to skip the current iteration. \n The difference between these statements is that in the case of break statement, the iteration stops and breaks out of loop, whereas, in the case of continue, the iteration is skipped but the loop continues to execute. \n Here's your task: \n Task 11:- \n Print numbers from 1 to 15. Skip the iteration if the number is a multiple of 3 and break out of the loop when it reaches 13."
  },
  {
    "task": "Fantastic! Now let's move on to arrays. \n Arrays are used to store multiple values in a single variable. It can be thought of as a collection of things of the same type. Like, a collection of roll numbers. \n Arrays are declared using []. Eg: let rollno = [1,2,3] \n Here's your task: \n Task 13 \n Store the values 45,23,767,921 into an array and print the values of the array which are greater than 23. Use arrayname.length to get the length of the array."
  },
  {
    "task": "Now, let's move on to array methods. \n Arrays have a variety of methods which is of a lot of help in day-to-day tasks. \n Let's get to know them: 1. pop() - Used to remove the last item from the array. \n 2. push() - Used to insert an element to the end of the array. \n 3. shift() - Used to remove the first item from the array. \n 4. splice() - Used to replace the old elements with new elements to the array. \n 5. concat() - to merge two arrays. \n 6. sort() - to sort an array \n 7. reverse() - to reverse an array. \n 8. map() - creates a new array by performing a function on each element. \n Phew! That's a lot of methods. Let's now work with each of them with the help of this task. \n Task 14 \n Create an array with the values ABC, GHI, DEF and JKL. Do the following. 1. Remove JKL from the array.\n 2. Insert PQR into the array. \n 3. Remove ABC from the array. \n 4. Replace the values DEF and PQR with WER and ERT \n 5. Create another array with values 1,2,3 and merge it with the current array. \n 6. Sort the array. \n 7. Reverse the order of elements of the array. \n 8. Create another array with elements of the second array with elements doubled and print the newly created array. \n Print the output in every case."
  },
  {
    "task": "Keep up the good work! The next topic we will cover is functions. Functions are sections of code that execute other code and make it reusable. \nIn ES6 there are 2 main ways to declare a function, the function keyword and arrow functions.\n Syntax: function name(params) {\n   code\n} \nTask 12: Declare a function using the respective keyword that when given 2 numbers will add them together, then print out the result. The number pairs you need to test are 1+2, 10+15, 100+400"
  },
  {
    "task": "Fantastic! Let's now move on to objects. \n Objects are similar to variables except that they can take multiple values at a time. The values are written as name:value pairs. \n For eg: var car = {type:'Fiat', model:'500', color:'white'} \n Here's your task: \n Task 15 \n Create an object person with age: 75 and gender: female. Print the year of birth with the help of her age along with her gender."
  },
  {
    "task": "Now's let's learn about another object called the Math object. It allows you to perform mathematical operations. \n 1. Math.round() - Returns the nearest integer value by rounding off. \n 2. Math.pow(x,y) - Returns the power of x to the value y. \n 3. Math.sqrt() - Returns the square root. \n 4. Math.random() - Returns a random value between 0 and 1. \n 5. Math.ceil() - Returns the value rounded up to the nearest integer. \n 6. Math.floor() - Returns the value rounded down to the nearest integer. \n Here's your task: \n Task 16 \n 1. Print the rounded value of 5.57. \n 2. Find the value of 6^3 and print it. \n 3. Find the square root of 841. \n 4. Print the rounded up value of 5.3 \n 5. Print the rounded down value of 5.3"
  },
  {
    "task": "Awesome! Let's now move on to switch statement. The switch statement is used to perform different operations based on different inputs. \n Syntax: \n switch(variable) { \n case 1: \n do something \n break; \n case 2: \n do something else \n break; .... \n default: \n Print invalid choice \n} \n Here's your task: \n Task 17 \n Receive the current day as a number using the Date.getDay() which returns the values 0-6 (0 - Sunday, 1 - Monday, etc). Based on the value received, print the day on the basis of the value returned. Use switch statement."
  },
  {
    "task": "Impressive! Let's now move on to Type Conversion. \n Variables can be converted to other datatypes using the in-built function or is converted automatically by JS. \n Here's your task: \n Task 18 \n Convert the boolean values true and false to string and print their type using the typeof function. Now store true and false in other variables and print their type. Note the difference in types."
  },
  {
    "task": "Awesome! Let's understand scope of a variable. \n Scopes define the value of the variable according to which it is defined. It can be of global or local scope.\n Global scope means that the variable can be accessed from any block of the program. Local scope means that the variable can only be accessed by the block in which it is declared in. \n To illustrate this, let's do the next task. \n Task 19 \n Declare a variable inside a function and set a value 4 to it and print it inside the function. Declare the variable with the same name outside the function block with the value 10 and print it there. \n Note the different values of the same variable printed based on its scope."
  },
  {
    "task": "Now, let's move on to Javascript reduce method. \n The reduce() is used to apply a function to each element in the array to reduce the array to a single value. \n Let's now find the sum of elements of an array without using the loops. This can be done using the reduce() method. \n Syntax: array.reduce(function(total, currentValue, currentIndex, arr), initialValue) \n Here's your task: \n Task 20 \n Find the sum of elements of an array with values 11.21, 19.21, 46.21. Do not use any loops. Use reduce()."
  },
  {
    "task": "Fantastic! Let's now move on to Javascript filter() method. \n The name itself describes it's purpose. It is used to filter elements of the array according to a particular condition. \n Syntax: let newArray = array.filter(function(item) { \n return condition;\n });\n Task 21 \n Use the filter() to find the values of the array containing values 1,3,4,6,8,9 that are divisible by 3 and print the values as output. Do not use any loops or if statements to find the solution. Use filter function only."
  },
  {
    "task": "Impressive! Let's move on to some other array method, the indexOf() method. \n This method searches for the given element from the given starting index and returns the index of the element if found or -1 if not found. \n Syntax: array.indexOf(item, start) \n Here's your task: \n Task 22 \n Store values 3,9,12,15,18 into an array and search for the element 15 starting from index 2 and then print its index. Then search for 14 starting from index 1 and print the value returned."
  },
  {
    "task": "Great work! Let's now learn about keys() method. This is used for returning properties of an object or an array. \n This method returns values that are keys of the key value pair stored. \n Syntax: Object.keys(obj) \n Here's your task: \n Task 23 \n Create an object with key-value pairs \n name: 'ABC', education: 'CSE' and print the values of the keys of the object. \n Also define an array with values A,B,C. Use keys() to obtain the properties of that array and print them."
  },
  {
    "task": "Now let's move on to JSON methods. The first one is JSON.parse(). It is used to parse a string written in JSON format and return a JavaScript object. \n Syntax: JSON.parse(string, function) \n Here's your task: \n Task 24 \n Create a JSON object\n var text = '{ 'name':'John', 'age':'39', 'city':'New York'}';\n Use the parse() to replace the value of city with Capital Case."
  },
  {
    "task": "Great! The second one is JSON.stringify(). This method is used to convert JS Objects into strings. \n Syntax: JSON.stringify(obj, replacer, space) \n Here's your task: \n Task 25 \n Create an object {x: 5, y: 6} and convert it into a string using stringify() and print the returned value."
  },
  {
    "task": "Awesome! Let's now move on to includes() method. This is used to check whether if an element is present in an array or a string. \n Task 26 \n Create an array with elements Mission, Vision, & Dedication. Search the array for the elements Mission & Success. Print the value returned. Note that it is CASE SENSITIVE."
  },
  {
    "task": "Fantastic! Here are some extras! Let's learn for of loop & foreach loop. \n We had learned for in loop before.\n foreach is an method that is available only in Array objects. It allows you to iterate through elements of an array. \n for of is a new way for iterating collections. Its introduced in ES6.\n For for of to work on an collection, the collection must have an [Symbol.iterator] property.\n Here's your task: \n Task 27 \n Create an array with elements abc,bcd,def. Loop through it using foreach, for of, for in loops. \n Note the difference in output."
  },
  {
    "task": "Amazing! Let's now move on to split() and join() methods. \n split() is used to split the string into an array by specifying a delimiter. \n join() is used to join the array elements into a string based on a delimiter. \n Here's your task: \n Task 28 \n Create a variable with the string JS is AWESOME! and split it on the basis of blank spaces. \n Print the splitted array elements. \n Then create another array with element , I, love, JS! and convert it into a string and print it."
  },
  {
    "task": "Great! Let's now move on to some more String Manipulation methods. \n startsWith(), endsWith(), substring(), substr()\n startsWith is used to check whether the string starts with a particular substring or not \n endsWith is used to check whether the string ends with a particular substring or not. \n substring is used to extract a particular part of a string. \n substr is also used to extract a particular part of the string except that it prints including the end index element. \n Here's your task: \n Task 29 \n Initialize a variable with the string Hello, I am a novice JS Developer. and check whether the string starts with Hello and whether it ends with Develop. Print the output. Then initialize another string with the value I am a Polyglot and extract the word Polyglot and print it. Then extract -  am a Polyglot and print it. Use substring() and substr() to obtain the output."
  },
  {
    "task": "Congrats! You have made it to the last task! \n Here's the task: \n Task 30 \n Use setInterval(), clearInterval(), and setTimeout() to print the values 1 to 5 with an interval from 1000 to 6000."
  }
]

================================================
FILE: src/workspace/python/solutions/task1.py
================================================
print('Hello World')


================================================
FILE: src/workspace/python/solutions/task10.py
================================================
a = 60
b = 100
c = 200
avg = ((a+b+c)/3)
print(int(avg))


================================================
FILE: src/workspace/python/solutions/task11.py
================================================
a = 10
b = 12.506
sum = a+b
avg = sum/2
print(sum)
print(avg)


================================================
FILE: src/workspace/python/solutions/task12.py
================================================
str = ' This is Cool!'
print(str.strip())
print(len(str))
print(str.lower())
print(str.upper())
print(str.replace("T","t"))


================================================
FILE: src/workspace/python/solutions/task13.py
================================================
str = 'Friday'
print(str[3:7])


================================================
FILE: src/workspace/python/solutions/task14.py
================================================
str = 'AJCE'
print(str[::-1])


================================================
FILE: src/workspace/python/solutions/task15.py
================================================
def area(side):
    print(side*side)
area(20)


================================================
FILE: src/workspace/python/solutions/task16.py
================================================
def div(number = 3):
    if(number%3 == 0):
        print("Divisible")
    else:
        print("Not Divisible")

div(16)
div()


================================================
FILE: src/workspace/python/solutions/task17.py
================================================
def my_func(value):
    return 17*value
a = my_func(14)
print(a)


================================================
FILE: src/workspace/python/solutions/task18.py
================================================
import time

localtime = time.asctime(time.localtime(time.time()) )
print(localtime)


================================================
FILE: src/workspace/python/solutions/task19.py
================================================
import math
def square_root(value):
    return math.sqrt(value)
a = square_root(3364)
print(a) 


================================================
FILE: src/workspace/python/solutions/task2.py
================================================
print('variable')
print('product_of_12')


================================================
FILE: src/workspace/python/solutions/task20.py
================================================
random_list = [1,2,3,4,5,6,7,8,9,10]
for i in random_list:
    if i%2==0:
        print(i)
    else:
        continue


================================================
FILE: src/workspace/python/solutions/task21.py
================================================
list = [1,2,3,4,5,6,7,8,9,10]
[ print(i) for i in list if i%2!=0 ]


================================================
FILE: src/workspace/python/solutions/task22.py
================================================
random_list = ['one', 'two', 'three']
def display(random_list):
    for i in random_list:
        print(i)

if 'one' in random_list:
    print('Found!')
else:
    print('Not Found!')
print(len(random_list))
random_list.append('four')
display(random_list)
random_list.insert(1, 'five')
display(random_list)
random_list.remove('one')
display(random_list)
random_list.pop(0)
display(random_list)
del random_list[1]
display(random_list)
random_list.clear()
print('Empty!')


================================================
FILE: src/workspace/python/solutions/task23.py
================================================
random_tuple = (100,200,300)
for i in random_tuple:
    print(i)
if 200 in random_tuple:
    print('Found!')
else:
    print('Not Found!')
print(len(random_tuple))


================================================
FILE: src/workspace/python/solutions/task24.py
================================================
dict_random = {1:'one', 2: 'two', 3: 'three'}
for i in dict_random:
    print(i)
for i in dict_random:
    print(dict_random[i])
for i,j in dict_random.items():
    print(i,j)
print(len(dict_random))
dict_random[4] = 'four'
for i,j in dict_random.items():
    print(i,j)


================================================
FILE: src/workspace/python/solutions/task25.py
================================================
try:
    print(1/0)
except:
    print('Zero Division not possible')


================================================
FILE: src/workspace/python/solutions/task26.py
================================================
def factorial(n):
    if n == 1:
        return 1
    else:
        return n*factorial(n-1)
a = factorial(6)
print(a)


================================================
FILE: src/workspace/python/solutions/task27.py
================================================
for i in range(1,5):
    for j in range(1,i+1):
        print('*', end='')
    print('\n')


================================================
FILE: src/workspace/python/solutions/task28.py
================================================
for i in range(1,11):
    print(5*i)


================================================
FILE: src/workspace/python/solutions/task29.py
================================================
a = 103
k = 0
for i in range(2,a//2+1):
    if(a%i==0):
        k=k+1
if(k<=0):
    print("Prime!")
else:
    print("Not Prime!")


================================================
FILE: src/workspace/python/solutions/task3.py
================================================
str = 'hello world'
print(str.upper())
print(len(str))


================================================
FILE: src/workspace/python/solutions/task30.py
================================================
string = 'civic'
if(string==string[::-1]):
      print("Palindrome!")
else:
      print("Not Palindrome!")


================================================
FILE: src/workspace/python/solutions/task4.py
================================================
a = 35
b = 30
c = 20
sum = a+b+c
avg = sum/3
print(sum)
print(avg)

================================================
FILE: src/workspace/python/solutions/task5.py
================================================
a = 20
if a%2==0:
	print("Even")
else:
	print("Odd")

================================================
FILE: src/workspace/python/solutions/task6.py
================================================
for i in range(1,11):
	if i%2 == 0:
		print(i)

================================================
FILE: src/workspace/python/solutions/task7.py
================================================
i = 1
while i<=10:
	print(i*i)
	i = i+1


================================================
FILE: src/workspace/python/solutions/task8.py
================================================
for i in range(10,20):
	if(i == 15):
		continue
	if(i == 18):
		break
	print(i)

================================================
FILE: src/workspace/python/solutions/task9.py
================================================
a = 90
b = 85
c = 70
d = 75
e = 80
avg = ((a+b+c+d+e)/5)
print(avg)
if avg>90 and avg<100:
    print('A+')
elif avg>80 and avg<=90:
    print('A')
elif avg>70 and avg<=80:
    print('B')
elif avg>60 and avg<=70:
    print('C')
elif avg>50 and avg<=60:
    print('D')
else:
    print('F')


================================================
FILE: src/workspace/python/tasks.json
================================================
[
  {
    "task": "Hey there folks, welcome to the world of programming\n Task 1:-\n Print Hello World to the console using the pre-built print function"
  },
  {
    "task": "\n Now lets focus on variables\n Unlike other programming languages, Python has no command for declaring a variable.A variable is created the moment you first assign a value to it.\n Also consider these variable naming conventions\n\n 1.A variable name must start with a letter or the underscore character\n 2.A variable name cannot start with a number\n 3.A variable name can only contain alpha-numeric characters and underscores (A-z, 0-9, and _ )\n 3.Variable names are case-sensitive (age, Age and AGE are three different variables)\n Task 2:-\n Consider these variable names:-\n variable\n sum@\n product_of_12\n 12_product\n Just print out the correct variable names in order"
  },
  {
    "task": "\nKeep it up!\nStrings represent a group of characters. String literals in python are surrounded by either single quotation marks, or double quotation marks.Python provides various prebuilt functions to deal with strings, say to find the length of a string, convert it to lower case etc.\nTask-3\nDeclare a variable str and initialize it with hello world Print it in upper case and also the length in order"
  },
  {
    "task": "\nGreat work! Let's move on .... \n Operators are used to perform operations on variables and values. \n There are many types of operators: \n 1. Arithmetic Operator \n 2. Assignment Operator \n 3. Comparison Operator \n 4. Logical Operator \n 5. Bitwise Operator \n Enough talk, let's do the task. \n\n Task 4 \n Initialize three variables a, b,c with values 35, 30, 20 respectively. \n Your task is to print the sum and average of these three numbers."
  },
  {
    "task": "\n Impressive! On to the next task ... \n Conditional Statements are statements that execute when the given condition is TRUE. \n Conditional statements are implemented using if-else statements. Here's your task: \n\n Task 5 \n Store value 20 to the variable 'a', then print 'Odd' if it is odd. Else, print 'Even' if it is an even number."
  },
  {
    "task": "\n Awesome! Let's move on to Loops. \n Loop is an important statement which is used for repetition of the same code as and when required. \n This task will surely test what you have learnt till now from the previous tasks! \n\n Task 6 \n Syntax of for loop: \n  for loop_control_variable in range(start, stop, step): \n \t Loop Body(indented)\n Here's your task:  \n\n Task- 6 \n Print even numbers from 1 to 10 (including 10) using for loop."
  },
  {
    "task": "\n Let's move on to while loop now. This loop works similiar to that of a for loop. \n Syntax of while loop: \n while condition:\n\tLoop Body(Indented statements). \n\n Task 7 \n Your task is to print the squares of the numbers from 1 to 10. Use while loop to do the task."
  },
  {
    "task": "\n Great work! Let's move on to break and continue statements. \n Break statements are used to break out of the loop when required and continue statements are used to skip the current iteration according to the condition given. \n\n Task 8: \n Print the values from 10 to 20 but skip the value 15 and stop the iteration at value 18. "
  },
  {
    "task": "\n Let's move on to Logical Operators. Logical Operators are 'and', 'or', 'not'. \n And operator returns true if both the conditions(operands) are true. \n Or operator returns true if any one of the conditions is True. \n Not operator negates the boolean value returned by the expression \n\n Task 9 \n Rahul scores 90, 85,70, 75, 80 in his exams. The grading criteria for an exam is given below(based on average): \n A+ => 91 -100 \n A => 81-90 \n B => 71-80 \n C => 61- 70 \n D => 51- 60 \n F => 50 & Less than 50. \n Calculate and print his average as well as the grade."
  },
  {
    "task": "\n Awesome! Let's move on to Type Conversion in Python. \n Type Conversion is used to directly convert one datatype to another which is useful in day-to day programming. \n For example, you may want to find the average as an integer without that long trailing numbers after the decimal point. For this, we can use type conversion. \n\n Task 10 \n Initialise three variables with the values 60,100,200 and find the average. Print the average as an integer."
  },
  {
    "task": "\n Now let's move on to Type Coercion in Python. \n Coercion happens in the case of binary operations: if you do x+y , and x and y have different types, \n they are coerced into a single type before performing the operation. \n\n Task 11 \n Initialize two numbers with values 10 and 12.506. Add them and print their sum and average. (This is the way how Python handles two datatypes by default)."
  },
  {
    "task": "\n Wonderful progress! Let's move on ... \n Now that you have learnt strings, let's move on to some in-built functions for strings. \n They are: \n 1.strip() - To remove any whitespace from beginning or the end \n 2. len() - To find the length of the string \n 3. lower() - Returns the string in lower case \n 4. upper() - Returns the string in upper case \n 5. replace() - To replace the value in the string with another value. \n\n Task 12 \n Store a string, ' This is Cool!' \n Your task is to \n 1. Remove the white spaces at the beginning and the end and print it. \n 2. Find the length of the string and print it. \n 3. Print it in lower case. \n 4. Print it in upper case \n 5. Replace T with t and print it."
  },
  {
    "task": "\n Great! Now, let's learn about String Slicing. \n To slice a string means to split a string into a substring. \n A string is a character array which has index starting from 0. \n To print the string, you can either directly print it or use it to print a part of it. \n Eg: \n b='Hello' \n print(b[1:4]) \n This prints the characters from index 1 to 4 (4 not included). Here's your task: \n\n Task 13 \n Print the substring 'day' in 'Friday'."
  },
  {
    "task": "\n Let's deal with strings again. The last character of the string can be accessed at the index -1. Use this logic to do the following task. \n Task 14 \n Reverse the string 'AJCE' and print it using for loop."
  },
  {
    "task": "\n Great. You have now mastered the basics of strings. \n Let's move on to the next topic: Functions. \n Functions are block of statements that execute a particular task. \n Functions are very useful in programs to shorten the length of the program, by not writing the same thing over and over again. \n You can pass values to a function, which are known as arguments. \n Syntax: \n def func_name(arguments): \n\tFunction Body \n The function body executes only when it is called, like this, func_name(arguments) \n Now, here's your task:\n\n Task 15\n Define a function that calculates area of a square. Pass the value side which is initialized to 20 and print the area by using the function."
  },
  {
    "task": "\n Awesome! Let's move on to the next topic: Default Parameters. \n The default parameters are used when you don't pass any values to the function. \n Eg: \n def func_name(default value=0): \n\tFunction Body \n When no value is passed, the default value of the argument is 0. Here's your task: \n\n Task 16 \n Define a function to check whether a number is divisible by 3 or not. Set the default value to 3.\n Pass the value 16 to the function and in the next statement, call the function without any argument. \n Print 'Divisible' if divisible by 3 else print 'Not Divisible'"
  },
  {
    "task": "\n Let's move on to return values. \n Return values are values that are returned after the function performs the required function. \n Syntax: return(value) \n Here's your next task: \n\n Task 17 \n Write a function that returns the (17*Value) and print the return value of the function. Pass the value 14 to the function and store the return value into a variable 'a' \n Print the value of 'a'"
  },
  {
    "task": "\n Awesome! You have mastered the basics of Functions. Let's move on to the next topic: Modules. \n A Module is a file consisting of Python code. A module can define functions, classes and variables. A module can also include runnable code.\n Most commonly used modules are: math, time, os. \n In order to use their functions, we can import them like: import module_name and use the functions defined inside the module by modulename.func_name(). Here's your task: \n\n Task 18 \n Use the time module to print the current local time of your desktop. \n Output Example: Thu Nov  1 18:42:18 2018"
  },
  {
    "task": "\n Impressive! Let's learn about the module math. \n 'math' module gives access to mathematical functions used to calculate cos, sin values, min, max, exp. \n Here's your task: \n\n Task 19 \n Write a program to define a function which returns the square root of the value passed to it. Return the square root and print it. Import math module and use sqrt(). \n Pass the value 3364."
  },
  {
    "task": "\n Great work! You have reached the 20th Task!! \n You have mastered the basics of modules. \n Now let's move on to the next topic: Collection Data Types. \n There are 4 collection datatypes. Let's begin with Lists. \n A list is a collection which is ordered and which can be changed. \n List elements are enclosed with Square Brackets []. Eg: randomlist = ['one','two'] \n List stores the values in an order. It start with an index 0. \n To access the first element in the list, you have to use list[0]. The first element is always stored in the index 0. \n For traversing through a list, you can use a for loop. Eg: for i in list_name: \n\tprint(i) \n Here's your task: \n\n Task 20 \n Create a list with elements 1 to 10 and traverse through the list and print the even numbers."
  },
  {
    "task": "\nWow! That's impressive! \n Let's learn List Comprehensions. \n List comprehensions provide a concise way to create lists. \n It consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses.\n The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it. \n Syntax: [ expression for item in list if conditional ] \n This is equivalent to what you did in the previous task. \n\n Task 21 \n Store numbers 1 to 10 in a list and print the odd numbers using List Comprehensions."
  },
  {
    "task": "\n Let's deal with lists some more. There are many operations that can be performed on Lists. \n They are: \n 1. Checking whether the element exists in the list using 'in' keyword. \n 2. To determine length of the list using len() \n 3. To add items using append() \n 4. To insert at specific index using insert() \n 5. To remove a particular element using remove(element) \n 6. Pop() - Removes at specified index or by default, the last one. \n 7. del keyword removes the specified index. \n 8.  clear() - Empties the whole list. \n Here's your task.(Quite a hectic task!) \n\n Task 22 \n Create a list with the values 'one', 'two', 'three'. Your task is to do the following: \n 1. Search for the element one and print 'Found!' if found, else print 'Not Found!' \n 2. Print the length of the list \n 3. Add 'four' to the list using append() \n 4. Insert 'five' at index 1 using insert() \n 5. Remove 'one' from the list using remove() \n 6. Remove the value at index 0 using pop() \n 7. Delete the second element of the list using del \n 8. Empty the remaining list and print 'Empty!' \n Use a function display() to display the list after each and every operation."
  },
  {
    "task": "\n Awesome! Now you have mastered the basics of Lists. \n Let's go to the next one: Tuples. \n A tuple is a collection which is ordered and unchangeable. In Python tuples are written with round brackets (). The only difference between List and Tuple is that you cannot modify the values of the list once created. \n That means you cannot add or remove elements to the tuple. \n This makes your next task easier :) \n\n Task 23 \n Create a tuple with values 100,200,300 and perform the following operations: \n 1. Print each value of the tuple using for loop. \n 2. Check if '200' exists in the tuple using in keyword and print 'Found!' else print 'Not Found!'. \n 3. Print the length of the tuple."
  },
  {
    "task": "\n Now let's move on to the next one: Dictionaries. \nA dictionary is a collection which is unordered, changeable and indexed. In Python dictionaries are written with curly brackets{}, and they have keys and values. \n  Syntax: {key:value, key2:value2}\n Unlike Tuples, you can modify the values here, like this, dictionary_name['key']= new_value \n To print only the keys, \n for i in dictionary_name: \n\tprint(i) \n To print only the values, \n for i in dict_name: \n\tprint(dict_name[i]) \n To print both key and value, \n for i,j in dict_name.items(): \n\tprint(i,j) \n Here's your task: \n\n Task 24 \n Initialize a dictionary with the key:values : 1:'one', 2:'two', 3: 'three' Your task is to print the elements of the dictionary(1. Keys only, 2. Values only, 3. Both key and values together) and print the length of the dictionary. Also, add the key:value pair, 4:'four' directly by assigning them to the dictionary, and print the updated dictionary(keys and values)"
  },
  {
    "task": "\n We have come to the last section of Python basics. \n Congrats on reaching the 25th Task! \n Next topic is Exception Handling \n When an error occurs, or exception as we call it, Python will normally stop and generate an error message. These exceptions can be handled using the try statement. \n Eg: try: \n\tprint(i) \n except: \n\tprint('An Exception Occured') \n When the try block raises an error, the except block statement gets executed. Without this try-except block, the program may crash. \n Here's your task: \n\n Task 25 \n Try printing the value of 1/0 and print 'Zero Division not possible' in the except block."
  },
  {
    "task": "\n Congrats on Completing the tasks. Hope you are having a great go. Here are some bonus tasks. \n\n Task 26 \n Factorial Program. Print the factorial of 6 using whatever you have learnt from the previous tasks. \n Do not use the in-built functions."
  },
  {
    "task": "\n Impressive! Let's go to the next one. \n\n Task 27 \n Pattern Printing \n Print the following pattern \n * \n ** \n *** \n ****"
  },
  {
    "task": "\n Now let's move on to the next one. \n\n Task 28 \n Multiplication Table \n Print the multiples of 5 in order from 1 to 10."
  },
  {
    "task": "\n You are one task away from completing this... Great to see you progress... \n Next task: \n\n Task 29 \n Prime Number \n Check whether 103 is prime or not and print 'Prime!' if prime else print 'Not Prime!'"
  },
  {
    "task": "\n Congrats!! You have reached the last task!!! \n Next task: \n\n Task 30 (the last one! :) ) \n\n Task 30 \n Palindrome \n Check whether a string 'civic' is palindrome or not. Print 'Palindrome!' if yes, else print 'Not Palindrome!'"
  }
]
Download .txt
gitextract_u8y5xtqs/

├── .eslintrc.js
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── custom.md
│   │   └── feature_request.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── config.yml
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── __e2e__/
│   ├── cli.test.js
│   ├── commands/
│   │   ├── fetchtask.test.js
│   │   ├── init.test.js
│   │   ├── showkeys.test.js
│   │   └── submit.test.js
│   └── helpers/
│       └── test-utils.js
├── bin/
│   └── index.js
├── commitlint.config.js
├── docs/
│   ├── .vuepress/
│   │   └── config.js
│   ├── README.md
│   └── guide/
│       ├── README.md
│       ├── commands.md
│       ├── contributing.md
│       └── installation.md
├── package.json
└── src/
    ├── commands/
    │   ├── init.js
    │   ├── keys.js
    │   ├── submit.js
    │   └── tasks.js
    ├── utils/
    │   ├── constants.js
    │   ├── github.js
    │   ├── logger.js
    │   └── validate.js
    └── workspace/
        ├── js/
        │   ├── solutions/
        │   │   ├── task1.js
        │   │   ├── task10.js
        │   │   ├── task11.js
        │   │   ├── task12.js
        │   │   ├── task13.js
        │   │   ├── task14.js
        │   │   ├── task15.js
        │   │   ├── task16.js
        │   │   ├── task17.js
        │   │   ├── task18.js
        │   │   ├── task19.js
        │   │   ├── task2.js
        │   │   ├── task20.js
        │   │   ├── task21.js
        │   │   ├── task22.js
        │   │   ├── task23.js
        │   │   ├── task24.js
        │   │   ├── task25.js
        │   │   ├── task26.js
        │   │   ├── task27.js
        │   │   ├── task28.js
        │   │   ├── task29.js
        │   │   ├── task3.js
        │   │   ├── task30.js
        │   │   ├── task4.js
        │   │   ├── task5.js
        │   │   ├── task6.js
        │   │   ├── task7.js
        │   │   ├── task8.js
        │   │   └── task9.js
        │   └── tasks.json
        └── python/
            ├── solutions/
            │   ├── task1.py
            │   ├── task10.py
            │   ├── task11.py
            │   ├── task12.py
            │   ├── task13.py
            │   ├── task14.py
            │   ├── task15.py
            │   ├── task16.py
            │   ├── task17.py
            │   ├── task18.py
            │   ├── task19.py
            │   ├── task2.py
            │   ├── task20.py
            │   ├── task21.py
            │   ├── task22.py
            │   ├── task23.py
            │   ├── task24.py
            │   ├── task25.py
            │   ├── task26.py
            │   ├── task27.py
            │   ├── task28.py
            │   ├── task29.py
            │   ├── task3.py
            │   ├── task30.py
            │   ├── task4.py
            │   ├── task5.py
            │   ├── task6.py
            │   ├── task7.py
            │   ├── task8.py
            │   └── task9.py
            └── tasks.json
Download .txt
SYMBOL INDEX (9 symbols across 9 files)

FILE: __e2e__/helpers/test-utils.js
  constant CLI_PATH (line 6) | const CLI_PATH = join(__dirname, '..', '..', 'bin');

FILE: src/workspace/js/solutions/task14.js
  function add (line 1) | function add(a, b) {

FILE: src/workspace/js/solutions/task19.js
  function abc (line 2) | function abc() {

FILE: src/workspace/python/solutions/task15.py
  function area (line 1) | def area(side):

FILE: src/workspace/python/solutions/task16.py
  function div (line 1) | def div(number = 3):

FILE: src/workspace/python/solutions/task17.py
  function my_func (line 1) | def my_func(value):

FILE: src/workspace/python/solutions/task19.py
  function square_root (line 2) | def square_root(value):

FILE: src/workspace/python/solutions/task22.py
  function display (line 2) | def display(random_list):

FILE: src/workspace/python/solutions/task26.py
  function factorial (line 1) | def factorial(n):
Condensed preview — 97 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (144K chars).
[
  {
    "path": ".eslintrc.js",
    "chars": 824,
    "preview": "\nmodule.exports = {\n    extends: ['eslint:recommended', 'prettier'], // extending recommended config and config derived "
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 91,
    "preview": "ko_fi: jamesgeorge007\npatreon: jamesgeorge007\ncustom: https://www.paypal.me/jamesgeorge007\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 567,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Describe the "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/custom.md",
    "chars": 640,
    "preview": "---\nname: Custom issue template\nabout: Describe this issue template's purpose here.\ntitle: ''\nlabels: ''\nassignees: ''\n\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 613,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: 'feat:'\nlabels: feature-request\nassignees: ''\n\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 720,
    "preview": "<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request"
  },
  {
    "path": ".github/config.yml",
    "chars": 695,
    "preview": "# ProBot Request Info (https://probot.github.io/apps/request-info/)\n\nrequestInfoReplyComment: >\n  We would appreciate it"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 546,
    "preview": "name: CI\non:\n  push:\n  pull_request:\n    branches:\n      - master\n      - next\n  workflow_dispatch:\njobs:\n  job:\n    run"
  },
  {
    "path": ".gitignore",
    "chars": 1168,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# VS-Code config\n.vscode\n\n# vuepress dist\ndocs/.vuepre"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3352,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "LICENSE",
    "chars": 35149,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "README.md",
    "chars": 5509,
    "preview": "<p align=\"center\">\n  <a href=\"https://teachcode.madlabs.xyz/\"><img src=\"https://i.imgur.com/BuMZB6C.png\" width=\"240\" hei"
  },
  {
    "path": "__e2e__/cli.test.js",
    "chars": 272,
    "preview": "'use strict';\n\nconst test = require('ava');\n\nconst { run } = require('./helpers/test-utils');\n\ntest('supplying an unknow"
  },
  {
    "path": "__e2e__/commands/fetchtask.test.js",
    "chars": 6237,
    "preview": "'use strict';\n\nconst path = require('path');\nconst test = require('ava');\nconst fs = require('fs');\n\nconst { createUserC"
  },
  {
    "path": "__e2e__/commands/init.test.js",
    "chars": 1735,
    "preview": "'use strict';\n\nconst path = require('path');\nconst test = require('ava');\nconst fs = require('fs');\n\nconst { createUserC"
  },
  {
    "path": "__e2e__/commands/showkeys.test.js",
    "chars": 2509,
    "preview": "'use strict';\n\nconst path = require('path');\nconst test = require('ava');\nconst fs = require('fs');\n\nconst { run } = req"
  },
  {
    "path": "__e2e__/commands/submit.test.js",
    "chars": 4156,
    "preview": "'use strict';\n\nconst path = require('path');\nconst test = require('ava');\nconst fs = require('fs');\n\n// const workspaceP"
  },
  {
    "path": "__e2e__/helpers/test-utils.js",
    "chars": 1214,
    "preview": "const execa = require('execa');\nconst { join } = require('path');\n\nconst fileExtensionMap = require('../../src/utils/con"
  },
  {
    "path": "bin/index.js",
    "chars": 1465,
    "preview": "#!/usr/bin/env node\n\n'use strict';\n\nconst chalk = require('chalk');\nconst program = require('commander');\nconst leven = "
  },
  {
    "path": "commitlint.config.js",
    "chars": 70,
    "preview": "module.exports = {\n  extends: ['@commitlint/config-conventional'],\n};\n"
  },
  {
    "path": "docs/.vuepress/config.js",
    "chars": 684,
    "preview": "\nmodule.exports = {\n    title: 'teachcode',\n    description: 'Learn to code effectively',\n    head: [\n        ['link', {"
  },
  {
    "path": "docs/README.md",
    "chars": 553,
    "preview": "---\nhome: true\nheroImage: images/teachcode.png\nactionText: Get Started →\nactionLink: /guide/\nfeatures:\n- title: Learn Ef"
  },
  {
    "path": "docs/guide/README.md",
    "chars": 2162,
    "preview": "# teachcode\n\n> Brush up your programming skills right from the terminal.\n\n## How it works\n\nUsers are required to solve 3"
  },
  {
    "path": "docs/guide/commands.md",
    "chars": 716,
    "preview": "---\ntitle: 'Available Commands'\n---\n\n# Available Commands\n\n `teachcode` offers the following set of commands:-\n\n | comma"
  },
  {
    "path": "docs/guide/contributing.md",
    "chars": 1089,
    "preview": "---\ntitle: 'Contributing'\n---\n\n# Contributing\n\n## Guidelines\n\n1. Fork and clone the repository.\n2. Navigate to the proje"
  },
  {
    "path": "docs/guide/installation.md",
    "chars": 625,
    "preview": "---\ntitle: 'Installation'\n---\n\n# Installation\n\n## Prerequisites\n\n- [**npm**](https://www.npmjs.com/) is a package manage"
  },
  {
    "path": "package.json",
    "chars": 1766,
    "preview": "{\n  \"name\": \"teach-code\",\n  \"version\": \"1.3.2\",\n  \"description\": \"A tool to develop and improve a student’s programming "
  },
  {
    "path": "src/commands/init.js",
    "chars": 4255,
    "preview": "'use strict';\n\nconst chalk = require('chalk');\nconst fs = require('fs');\nconst inquirer = require('inquirer');\nconst sho"
  },
  {
    "path": "src/commands/keys.js",
    "chars": 1188,
    "preview": "'use strict';\n\nconst chalk = require('chalk');\nconst fs = require('fs');\nconst showBanner = require('node-banner');\n\ncon"
  },
  {
    "path": "src/commands/submit.js",
    "chars": 7415,
    "preview": "'use strict';\n\nconst chalk = require('chalk');\nconst { exec } = require('child_process');\nconst fs = require('fs');\ncons"
  },
  {
    "path": "src/commands/tasks.js",
    "chars": 3376,
    "preview": "'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\nconst showBanner = require('node-banner');\n\nconst"
  },
  {
    "path": "src/utils/constants.js",
    "chars": 197,
    "preview": "'use strict';\n\n// Holds a reference to the file extensions corresponding to the learning track\nconst fileExtensionMap = "
  },
  {
    "path": "src/utils/github.js",
    "chars": 3522,
    "preview": "'use strict';\n\nconst axios = require('axios');\nconst chalk = require('chalk');\nconst execa = require('execa');\nconst inq"
  },
  {
    "path": "src/utils/logger.js",
    "chars": 340,
    "preview": "'use strict';\n\nconst chalk = require('chalk');\n\nconst error = msg => console.error(chalk.red.bold(msg));\n\nconst info = m"
  },
  {
    "path": "src/utils/validate.js",
    "chars": 275,
    "preview": "'use strict';\n\n/**\n * Validate user input\n *\n * @param {String} userInput\n * @returns {Boolean}\n */\n\nconst validateInput"
  },
  {
    "path": "src/workspace/js/solutions/task1.js",
    "chars": 28,
    "preview": "console.log('Hello World');\n"
  },
  {
    "path": "src/workspace/js/solutions/task10.js",
    "chars": 145,
    "preview": "let s = 1;\ndo {\n  if (s % 2 === 0) {\n    console.log(s + ' is even.');\n  } else {\n    console.log(s + ' is odd.');\n  }\n "
  },
  {
    "path": "src/workspace/js/solutions/task11.js",
    "chars": 153,
    "preview": "let i = 1;\nwhile (i <= 15) {\n  if (i % 3 === 0) {\n    i++;\n    continue;\n  } else if (i === 13) {\n    break;\n  } else {\n"
  },
  {
    "path": "src/workspace/js/solutions/task12.js",
    "chars": 108,
    "preview": "let no = [45, 23, 767, 921];\n\nfor (let i = 0; i < no.length; i++) {\n  if (no[i] > 23) console.log(no[i]);\n}\n"
  },
  {
    "path": "src/workspace/js/solutions/task13.js",
    "chars": 343,
    "preview": "let a = ['ABC', 'GHI', 'DEF', 'JKL'];\nlet b = [1, 2, 3];\na.pop();\nconsole.log(a);\na.push('PQR');\nconsole.log(a);\na.shift"
  },
  {
    "path": "src/workspace/js/solutions/task14.js",
    "chars": 84,
    "preview": "function add(a, b) {\n  console.log(a + b);\n}\nadd(1, 2);\nadd(10, 15);\nadd(100, 400);\n"
  },
  {
    "path": "src/workspace/js/solutions/task15.js",
    "chars": 127,
    "preview": "let person = {\n  age: 75,\n  gender: 'female',\n};\n\nlet yyyy = 2019 - person.age;\nconsole.log(yyyy);\nconsole.log(person.ge"
  },
  {
    "path": "src/workspace/js/solutions/task16.js",
    "chars": 148,
    "preview": "console.log(Math.round(5.57));\nconsole.log(Math.pow(6, 3));\nconsole.log(Math.sqrt(841));\nconsole.log(Math.ceil(5.3));\nco"
  },
  {
    "path": "src/workspace/js/solutions/task17.js",
    "chars": 344,
    "preview": "let day;\nswitch (new Date().getDay()) {\n  case 0:\n    day = 'Sunday';\n    break;\n  case 1:\n    day = 'Monday';\n    break"
  },
  {
    "path": "src/workspace/js/solutions/task18.js",
    "chars": 172,
    "preview": "let a = true.toString();\nlet b = false.toString();\nconsole.log(typeof a);\nconsole.log(typeof b);\nlet c = true;\nlet d = f"
  },
  {
    "path": "src/workspace/js/solutions/task19.js",
    "chars": 86,
    "preview": "let a = 10;\nfunction abc() {\n  let a = 4;\n  console.log(a);\n}\n\nabc();\nconsole.log(a);\n"
  },
  {
    "path": "src/workspace/js/solutions/task2.js",
    "chars": 34,
    "preview": "const str = 18;\nconsole.log(str);\n"
  },
  {
    "path": "src/workspace/js/solutions/task20.js",
    "chars": 120,
    "preview": "const pounds = [11.21, 19.21, 46.21];\n\nconst sum = pounds.reduce((total, amount) => total + amount);\n\nconsole.log(sum);\n"
  },
  {
    "path": "src/workspace/js/solutions/task21.js",
    "chars": 170,
    "preview": "const numbers = [1, 3, 4, 6, 8, 9];\n\nconst filterValues = () => {\n  return numbers.filter(number => {\n    return number "
  },
  {
    "path": "src/workspace/js/solutions/task22.js",
    "chars": 90,
    "preview": "let a = [3, 9, 12, 15, 18];\nconsole.log(a.indexOf(15, 2));\nconsole.log(a.indexOf(14, 1));\n"
  },
  {
    "path": "src/workspace/js/solutions/task23.js",
    "chars": 139,
    "preview": "let obj = {\n  name: 'ABC',\n  education: 'CSE',\n};\nconsole.log(Object.keys(obj));\nlet arr = ['A', 'B', 'C'];\nconsole.log("
  },
  {
    "path": "src/workspace/js/solutions/task24.js",
    "chars": 224,
    "preview": "let text = '{ \"name\":\"John\", \"age\":\"39\", \"city\":\"New York\"}';\nlet obj = JSON.parse(text, function(key, value) {\n  if (ke"
  },
  {
    "path": "src/workspace/js/solutions/task25.js",
    "chars": 45,
    "preview": "console.log(JSON.stringify({ x: 5, y: 6 }));\n"
  },
  {
    "path": "src/workspace/js/solutions/task26.js",
    "chars": 129,
    "preview": "let goals = ['Mission', 'Vision', 'Dedication'];\nconsole.log(goals.includes('Mission'));\nconsole.log(goals.includes('Suc"
  },
  {
    "path": "src/workspace/js/solutions/task27.js",
    "chars": 194,
    "preview": "const array1 = ['abc', 'bcd', 'cde'];\n\narray1.forEach(item => console.log(item));\nfor (const element of array1) {\n  cons"
  },
  {
    "path": "src/workspace/js/solutions/task28.js",
    "chars": 139,
    "preview": "let str = 'JS is AWESOME!';\nlet arr = str.split(' ');\nconsole.log(arr);\nlet a = ['I', 'love', 'JS!'];\nlet s = a.join(' '"
  },
  {
    "path": "src/workspace/js/solutions/task29.js",
    "chars": 289,
    "preview": "let str = 'Hello, I am a novice JS Developer.';\nconsole.log(str.startsWith('Hello'));\nconsole.log(str.endsWith('Develop'"
  },
  {
    "path": "src/workspace/js/solutions/task3.js",
    "chars": 45,
    "preview": "const str = 'JS is cool!';\nconsole.log(str);\n"
  },
  {
    "path": "src/workspace/js/solutions/task30.js",
    "chars": 203,
    "preview": "let counter = 0;\n\nconst startCounter = () => {\n  counter++;\n  process.stdout.write(`${counter} `);\n};\n\nconst interval = "
  },
  {
    "path": "src/workspace/js/solutions/task4.js",
    "chars": 269,
    "preview": "const str = ' Hey, this is Task 4 of JS Path! ';\nconsole.log(str.length);\nconsole.log(str.indexOf('Task'));\nconsole.log("
  },
  {
    "path": "src/workspace/js/solutions/task5.js",
    "chars": 149,
    "preview": "const a = 25;\nconst b = 33;\nconsole.log(a + b);\nconsole.log(a - b);\nconsole.log(a * b);\nconsole.log(a / b);\nconsole.log("
  },
  {
    "path": "src/workspace/js/solutions/task6.js",
    "chars": 210,
    "preview": "const a = 44;\nconst b = 29;\n// eslint-disable-next-line eqeqeq\nconsole.log(a == b);\nconsole.log(a === b);\nconsole.log(a "
  },
  {
    "path": "src/workspace/js/solutions/task7.js",
    "chars": 122,
    "preview": "const a = 34;\nconst b = 23;\nconst c = 1;\nconsole.log(a > b && a < c);\nconsole.log(a < b || a > c);\nconsole.log(!(b < a))"
  },
  {
    "path": "src/workspace/js/solutions/task8.js",
    "chars": 79,
    "preview": "for (let i = 1; i <= 12; i++) {\n  if (i % 4 === 0) {\n    console.log(i);\n  }\n}\n"
  },
  {
    "path": "src/workspace/js/solutions/task9.js",
    "chars": 119,
    "preview": "let x = 1;\nwhile (x <= 50) {\n  if (x % 5 === 0) {\n    console.log('Buzz');\n  } else {\n    console.log(x);\n  }\n  x++;\n}\n"
  },
  {
    "path": "src/workspace/js/tasks.json",
    "chars": 14913,
    "preview": "[\n  {\n    \"task\": \"Hey there folks, you have chosen JS Path! \\n Here's your first task! All the best...\\n Task 1:-\\n Pri"
  },
  {
    "path": "src/workspace/python/solutions/task1.py",
    "chars": 21,
    "preview": "print('Hello World')\n"
  },
  {
    "path": "src/workspace/python/solutions/task10.py",
    "chars": 57,
    "preview": "a = 60\nb = 100\nc = 200\navg = ((a+b+c)/3)\nprint(int(avg))\n"
  },
  {
    "path": "src/workspace/python/solutions/task11.py",
    "chars": 62,
    "preview": "a = 10\nb = 12.506\nsum = a+b\navg = sum/2\nprint(sum)\nprint(avg)\n"
  },
  {
    "path": "src/workspace/python/solutions/task12.py",
    "chars": 124,
    "preview": "str = ' This is Cool!'\nprint(str.strip())\nprint(len(str))\nprint(str.lower())\nprint(str.upper())\nprint(str.replace(\"T\",\"t"
  },
  {
    "path": "src/workspace/python/solutions/task13.py",
    "chars": 31,
    "preview": "str = 'Friday'\nprint(str[3:7])\n"
  },
  {
    "path": "src/workspace/python/solutions/task14.py",
    "chars": 30,
    "preview": "str = 'AJCE'\nprint(str[::-1])\n"
  },
  {
    "path": "src/workspace/python/solutions/task15.py",
    "chars": 46,
    "preview": "def area(side):\n    print(side*side)\narea(20)\n"
  },
  {
    "path": "src/workspace/python/solutions/task16.py",
    "chars": 127,
    "preview": "def div(number = 3):\n    if(number%3 == 0):\n        print(\"Divisible\")\n    else:\n        print(\"Not Divisible\")\n\ndiv(16)"
  },
  {
    "path": "src/workspace/python/solutions/task17.py",
    "chars": 65,
    "preview": "def my_func(value):\n    return 17*value\na = my_func(14)\nprint(a)\n"
  },
  {
    "path": "src/workspace/python/solutions/task18.py",
    "chars": 85,
    "preview": "import time\n\nlocaltime = time.asctime(time.localtime(time.time()) )\nprint(localtime)\n"
  },
  {
    "path": "src/workspace/python/solutions/task19.py",
    "chars": 96,
    "preview": "import math\ndef square_root(value):\n    return math.sqrt(value)\na = square_root(3364)\nprint(a) \n"
  },
  {
    "path": "src/workspace/python/solutions/task2.py",
    "chars": 41,
    "preview": "print('variable')\nprint('product_of_12')\n"
  },
  {
    "path": "src/workspace/python/solutions/task20.py",
    "chars": 118,
    "preview": "random_list = [1,2,3,4,5,6,7,8,9,10]\nfor i in random_list:\n    if i%2==0:\n        print(i)\n    else:\n        continue\n"
  },
  {
    "path": "src/workspace/python/solutions/task21.py",
    "chars": 67,
    "preview": "list = [1,2,3,4,5,6,7,8,9,10]\n[ print(i) for i in list if i%2!=0 ]\n"
  },
  {
    "path": "src/workspace/python/solutions/task22.py",
    "chars": 469,
    "preview": "random_list = ['one', 'two', 'three']\ndef display(random_list):\n    for i in random_list:\n        print(i)\n\nif 'one' in "
  },
  {
    "path": "src/workspace/python/solutions/task23.py",
    "chars": 164,
    "preview": "random_tuple = (100,200,300)\nfor i in random_tuple:\n    print(i)\nif 200 in random_tuple:\n    print('Found!')\nelse:\n    p"
  },
  {
    "path": "src/workspace/python/solutions/task24.py",
    "chars": 271,
    "preview": "dict_random = {1:'one', 2: 'two', 3: 'three'}\nfor i in dict_random:\n    print(i)\nfor i in dict_random:\n    print(dict_ra"
  },
  {
    "path": "src/workspace/python/solutions/task25.py",
    "chars": 68,
    "preview": "try:\n    print(1/0)\nexcept:\n    print('Zero Division not possible')\n"
  },
  {
    "path": "src/workspace/python/solutions/task26.py",
    "chars": 118,
    "preview": "def factorial(n):\n    if n == 1:\n        return 1\n    else:\n        return n*factorial(n-1)\na = factorial(6)\nprint(a)\n"
  },
  {
    "path": "src/workspace/python/solutions/task27.py",
    "chars": 91,
    "preview": "for i in range(1,5):\n    for j in range(1,i+1):\n        print('*', end='')\n    print('\\n')\n"
  },
  {
    "path": "src/workspace/python/solutions/task28.py",
    "chars": 37,
    "preview": "for i in range(1,11):\n    print(5*i)\n"
  },
  {
    "path": "src/workspace/python/solutions/task29.py",
    "chars": 130,
    "preview": "a = 103\nk = 0\nfor i in range(2,a//2+1):\n    if(a%i==0):\n        k=k+1\nif(k<=0):\n    print(\"Prime!\")\nelse:\n    print(\"Not"
  },
  {
    "path": "src/workspace/python/solutions/task3.py",
    "chars": 55,
    "preview": "str = 'hello world'\nprint(str.upper())\nprint(len(str))\n"
  },
  {
    "path": "src/workspace/python/solutions/task30.py",
    "chars": 107,
    "preview": "string = 'civic'\nif(string==string[::-1]):\n      print(\"Palindrome!\")\nelse:\n      print(\"Not Palindrome!\")\n"
  },
  {
    "path": "src/workspace/python/solutions/task4.py",
    "chars": 66,
    "preview": "a = 35\nb = 30\nc = 20\nsum = a+b+c\navg = sum/3\nprint(sum)\nprint(avg)"
  },
  {
    "path": "src/workspace/python/solutions/task5.py",
    "chars": 52,
    "preview": "a = 20\nif a%2==0:\n\tprint(\"Even\")\nelse:\n\tprint(\"Odd\")"
  },
  {
    "path": "src/workspace/python/solutions/task6.py",
    "chars": 46,
    "preview": "for i in range(1,11):\n\tif i%2 == 0:\n\t\tprint(i)"
  },
  {
    "path": "src/workspace/python/solutions/task7.py",
    "chars": 40,
    "preview": "i = 1\nwhile i<=10:\n\tprint(i*i)\n\ti = i+1\n"
  },
  {
    "path": "src/workspace/python/solutions/task8.py",
    "chars": 79,
    "preview": "for i in range(10,20):\n\tif(i == 15):\n\t\tcontinue\n\tif(i == 18):\n\t\tbreak\n\tprint(i)"
  },
  {
    "path": "src/workspace/python/solutions/task9.py",
    "chars": 288,
    "preview": "a = 90\nb = 85\nc = 70\nd = 75\ne = 80\navg = ((a+b+c+d+e)/5)\nprint(avg)\nif avg>90 and avg<100:\n    print('A+')\nelif avg>80 a"
  },
  {
    "path": "src/workspace/python/tasks.json",
    "chars": 14987,
    "preview": "[\n  {\n    \"task\": \"Hey there folks, welcome to the world of programming\\n Task 1:-\\n Print Hello World to the console us"
  }
]

About this extraction

This page contains the full source code of the madlabsinc/teachcode GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 97 files (130.0 KB), approximately 34.9k tokens, and a symbol index with 9 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!