Merge pull request #85 from 30-seconds/from-starter

Use 30-seconds-starter template
This commit is contained in:
Angelos Chalaris
2019-08-21 10:43:11 +03:00
committed by GitHub
252 changed files with 31860 additions and 3947 deletions

8
.gitattributes vendored Normal file
View File

@ -0,0 +1,8 @@
src/docs/* linguist-documentation
scripts/* linguist-documentation
gatsby-browser.js linguist-documentation
gatsby-config.js linguist-documentation
gatsby-node.js linguist-documentation
gatsby-ssr.js linguist-documentation
.travis/* linguist-documentation
config.js linguist-documentation

81
.gitignore vendored
View File

@ -1,5 +1,80 @@
__pycache__/
# IDE Specific
.vscode
*.iml
.idea/codeStyles/Project.xml
*.xml
# dotenv environment variables file
.env
# gatsby files
.cache/
public
# Mac files
.DS_Store
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# 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 (http://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
yarn-error.log
.pnp/
.pnp.js
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# next.js build output
.next

View File

@ -1,17 +1,12 @@
sudo: false
language: python
cache: pip
python:
- "3.6"
language: node_js
cache:
directories:
- node_modules
node_js:
- lts/*
script:
- python scripts/lint.py
- python scripts/readme.py
- python scripts/tdd.py
- python website/main.py
- python scripts/auto-lint.py
- npm run extractor
- npm run builder
after_success:
- sed -i -e 's/\r$//' .travis/push.sh
- .travis/push.sh
env:
global:
- secure: RucoyHikFKD7yQq7FBHxOpwYSHSFYUO7QS/5VEXvU55AMnHwB97aI0DcQSMa+XHaSFVsqd4fR7nAP+5H6GMW/lUhIdeXIGzehgBTfuNeQmng2djGgS1lWY9fEOsn2XEL7JlXMi2P5YdZDpOAfiiLqT3W8EaCWDdV60tkizbSQhig2R3exI/649AjmGkIws+NqoYqrEfNpnTvgxJkp2jNuKfBkr0aaVdYuxdI6Kf2KnipEeuKsKJFds+tTjduEUKTg7I8lNSB+tQ9wIHNTDZffZrzODzE2esAZtnflxhkGQ6q7fW8DEj0rheuer+yD4WBWfph1CIxTL6B3VZgT6XQXCu09XzqgRUack0KIS6SBRKjRYJymH3eKNlxZGPpk4s90bX0Qo0a0vvcT4g/iejyVb917pcn2LjRZmmsFQUfJOcCJgU6EUvqNpfM9SWV8fJhaPOacvUnzDxFav3eRdDHaZYgXf0tzJfLAjsTv7rFbLZEnpqtvyKbHrXYLf9sICyPlHbCy4L5KAfguu735v0YPXko5Aabl6PvGcfafyLxVUb/0Y5ot3pLtGVJflfHeqYz8qbkoqp5RovSvTXntx/vVlx20TSE/rQP2l6JUNt98sGFJ+yOZ3SkMnyMdjE1YqeEngxZdzukec2SM3PtnaWxSbxV8Ue1XnM8D5nzhTf4UI8=
- chmod +x .travis/push.sh
- .travis/push.sh

View File

@ -1,17 +1,15 @@
#!/bin/bash
setup_git() {
git config --global user.email "mst10041967@gmail.com"
git config --global user.name "Rohit Tanwar"
git config --global user.email "30secondsofcode@gmail.com"
git config --global user.name "30secondsofcode"
}
commit_website_files() {
if [ $TRAVIS_EVENT_TYPE != "pull_request" ]; then
if [ $TRAVIS_BRANCH == "master" ]; then
git checkout master
echo "Committing to master branch..."
git add -A
echo "All files added"
git status
git checkout master
git add *
if [ $TRAVIS_EVENT_TYPE == "cron" ]; then
git commit --message "Travis build: $TRAVIS_BUILD_NUMBER [cron]"
elif [ $TRAVIS_EVENT_TYPE == "api" ]; then
@ -19,8 +17,6 @@ commit_website_files() {
else
git commit --message "Travis build: $TRAVIS_BUILD_NUMBER"
fi
echo "Files commited"
git status
fi
fi
}
@ -29,12 +25,7 @@ upload_files() {
if [ $TRAVIS_EVENT_TYPE != "pull_request" ]; then
if [ $TRAVIS_BRANCH == "master" ]; then
echo "Pushing to master branch..."
git push --force "https://${GH_TOKEN}@github.com/kriadmin/30-seconds-of-python-code.git" master > /dev/null 2>&1
echo "Pushing done"
echo "Pushing to website"
git subtree push --prefix website "https://${GH_TOKEN}@github.com/kriadmin/30-seconds-of-python-code.git" website
echo "Pushed to master branch"
git status
git push --force --quiet "https://${GH_TOKEN}@github.com/30-seconds/30-seconds-of-python.git" master > /dev/null 2>&1
fi
fi
}

23
COLLABORATING.md Normal file
View File

@ -0,0 +1,23 @@
# Collaborator team rules and guidelines for community moderation
**As a contributor/member of the community, remember that you can always open issues about moderation and problems with how community moderation is done. We are always open to constructive criticism and feedback!**
## Responsibilities of a collaborator
As a member of the team that manages **30 seconds of python code**, you have the following responsibilities:
- **Be part of the conversation in the issue tracker.** That includes (but is not limited to) helping out new members, discussing new features and explaining decisions to people.
- **Review pull requests.** You do not have to read through all of the pull requests and review them, but taking the time each day to review a few can help a great deal.
- **Be civil and polite.** If you are about to lose your temper, take a step back and do something else. We want our interactions with the community to be polite so that more people can join the project and contribute in any way they can. Remember to always thank contributors for their help, even if it's minor changes or changes that did not make it into the project. This way we can reward and encourage people to keep being part of the community.
- **Contribute when you want, moderate when you can.** If you have a lot on your plate outside of this project, it's alright. It's better to take a break for a few days rather than hastily deal with issues and pull requests that might break things.
## Guidelines for merging pull requests and making changes to the project
- **[Usual guidelines](https://github.com/30-seconds/30-seconds-of-python/blob/master/CONTRIBUTING.md) apply.** Make sure to follow them, like everybody else.
- **For a pull request to be considered ready to merge, there should be at least 2 (preferably 3) reviews approving it for merge.** There are, however, certain exceptions:
- **If a pull request only fixes typos**, there is no need to wait for a second reviewer (unless you are not certain these were not typos in the first place).
- **If a pull request only clarifies a snippet's description or enforces the style guide for an existing snippet**, you might be able to merge it without getting a second reviewer to review it, but only if you are certain about it.
- **Make sure pull requests pass the Travis CI build**, otherwise try and find out what's wrong and inform the author of the pull request.
- **Changes to build scripts, guidelines and things that might break the processes we have in place need to be reviewed by [@Chalarangelo](https://github.com/Chalarangelo) or [@fejes713](https://github.com/fejes713)**.
- **If you make changes or additions to existing snippets or if you want to add your own snippets, you will go through the pull request process that everyone else goes.** Exceptions apply similarly to the ones mentioned above about merging pull requests (i.e. typos, description clarification and the way script and build process changes are handled). Pull requests suggested by collaborators should be reviewed by at least two other collaborators to be considered ready to merge.
- **Pull requests that are inactive for over a week should be closed or put on hold.**

View File

@ -4,11 +4,11 @@
Here's what you can do to help:
- [Open issues](https://github.com/kriadmin/30-seconds-of-python-code/issues/new) for things you want to see added or modified.
- Be part of the discussion by helping out with [existing issues](https://github.com/kriadmin/30-seconds-of-python-code/issues) or talking on our [gitter channel](https://gitter.im/30-seconds-of-python-code/Lobby).
- Submit [pull requests](https://github.com/kriadmin/30-seconds-of-python-code/pulls) with snippets you have created (see below for guidelines).
- [Open issues](https://github.com/30-seconds/30-seconds-of-python/issues/new) for things you want to see added or modified.
- Be part of the discussion by helping out with [existing issues](https://github.com/30-seconds/30-seconds-of-python/issues) or talking on our [gitter channel](https://gitter.im/30-seconds-of-python/Lobby).
- Submit [pull requests](https://github.com/30-seconds/30-seconds-of-python/pulls) with snippets you have created (see below for guidelines).
- Fix typos in existing snippets, improve snippet descriptions and explanations or provide better examples.
- Before submitting a PR for any new snippets go through [this](https://github.com/kriadmin/30-seconds-of-python-code/projects/1) project. If your snippet is not there, then go ahead and submit a PR. Else if it is in the done column, sorry it has been already implemented. If it is in any other column submit a PR and give the card's link in the description section of PR.
- Before submitting a PR for any new snippets go through [this](https://github.com/30-seconds/30-seconds-of-python/projects/1) project. If your snippet is not there, then go ahead and submit a PR. Else if it is in the done column, sorry it has been already implemented. If it is in any other column submit a PR and give the card's link in the description section of PR.
- **Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
### Snippet submission and Pull request guidelines
@ -25,7 +25,7 @@ Here's what you can do to help:
- **Snippet descriptions** must be short and to the point. Try to explain *what* the snippet does and *how* the snippet works and what **inbuilt** features/modules are used. Remember to include what functions you are using and why.
- Follow snippet descriptions with an empty line.
- **Snippets _CAN NOT_ use any external modules**. Only the modules and function inbuilt in `python 3.6` shall be used.
- **Snippet code** must be enclosed inside ` ```python ` and ` ``` `.
- **Snippet code** must be enclosed inside ` ```py ` and ` ``` `.
- Remember to start your snippet's code on a new line below the opening backticks.
- You can write the code in any style you like but eventually it will be formated by our prettifier so the formatting will change. Just make sure to have consistent spacing.
- Try to keep your snippets' code short and to the point. Use modern techniques and features. Make sure to test your code before submitting.
@ -37,33 +37,4 @@ Here's what you can do to help:
- Snippets *should* be abstract enough to be applied to different scenarios.
- It is not mandatory but highly appreciated if you provide **test cases** and/or performance tests.
- You can start creating a new snippet, by using the [snippet template](snippet_template.md) to format your snippets.
- Updating the README.md file should only be done by altering the scripts in the **scripts** folder or altering their relative static parts in the **static-parts** folder.
- You may tag your snippet in tag_databse although it is _not_ necessary.
- You may add your name as `[Name][@github_username]` to the contributor database. If the snippet already exists and you are making changes to it you can add your name at the last seperated by a comma.
<!--
### Additional guidelines and conventions regarding snippets
- If your snippet contains argument with default parameters, explain what happens if they are omitted when calling the function and what the default case is.
- If your snippet uses recursion, explain the base cases.
- If your variable is not changed anywhere in the code name it in uppercase.
- Use `camelCase` for function and variable names if they consist of more than one word.
- Try to give meaningful names to variables. For example use `letter`, instead of `lt`. Some exceptions to convention are:
- `arr` for lists (usually as the snippet function's argument).
- `str` for strings.
- `n` for a numeric value (usually as the snippet function's argument).
- `val` or `v` for value (usually when iterating a list, mapping, sorting etc.).
- `i` for indexes.
- `func` for function arguments.
- `nums` for lists of numbers.
- Use `()` if your function takes no arguments.
- Specify default parameters for arguments, if necessary. It is preferred to put default parameters last unless you have pretty good reason not to.
- If your snippet's function takes variadic arguments, use `...args` (although in certain cases, it might be needed to use a different name).
- Always use single quotes for string literals.
- Prefer using the ternary operator (`trueResult if condition else falseResult`) instead of `if else` statements whenever possible.
- Avoid nesting ternary operators (but you can do it if you feel like you should).
- You should define multiple variables on the same line (e.g. `x,y = 0,1`) on the same line whenever possible.
- Do not use trailing or leading underscores in variable names(unless it is a helper function).
- Use lambda functions as much as possible, except when you can't.
- Leave a single space after a comma (`,`) character.
- Try to strike a balance between readability, brevity, and performance.
- Never use `eval()`. Your snippet will be disqualified immediately.-->
- Updating the README.md file should only be done by altering the scripts in the **scripts** folder or altering their relative static parts in the **static-parts** folder.

2470
README.md

File diff suppressed because it is too large Load Diff

4
_headers Normal file
View File

@ -0,0 +1,4 @@
[[headers]]
for = "/static/*"
[headers.values]
Cache-Control = "public, max-age=360000"

1
advanced.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="78" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect height="20" rx="3" fill="#fff" width="64"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h65v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"><text x="325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">advanced</text><text x="325" y="140" transform="scale(.1)" textLength="530">advanced</text></g> </svg>

After

Width:  |  Height:  |  Size: 695 B

BIN
assets/30s-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
assets/NotoSans-Italic.ttf Normal file

Binary file not shown.

BIN
assets/NotoSans-Light.ttf Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/NotoSans-Medium.ttf Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/NotoSans-Regular.ttf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -1,2 +0,0 @@
[tape]
python_files=*.test.py

15
config.js Normal file
View File

@ -0,0 +1,15 @@
module.exports = {
// Project metadata
name: `30 seconds of python`,
description: `A curated collection of useful Python snippets that you can understand in 30 seconds or less.`,
shortName: `30s`,
repositoryUrl: `https://github.com/30-seconds/30-seconds-of-python`,
// Path information
snippetPath: `snippets`,
snippetDataPath: `snippet_data`,
assetPath: `assets`,
pagePath: `src/docs/pages`,
staticPartsPath: `src/static-parts`,
// General information
language: `py`,
};

View File

@ -1,32 +0,0 @@
average:[Rohit Tanwar](@kriadmin),[Hui Binyuan](@huybery)
chunk:[Rohit Tanwar](@kriadmin)
compact:[Rohit Tanwar](@kriadmin)
count_occurences:[Rohit Tanwar](@kriadmin), [Hui Binyuan](@huybery)
count_vowels:[Rohit Tanwar](@kriadmin)
deep_flatten:[Rohit Tanwar](@kriadmin),[Meet Zaveri](@meetzaveri)
difference:[Rohit Tanwar](@kriadmin)
factorial:[Rohit Tanwar](@kriadmin)
gcd:[Rohit Tanwar](@kriadmin),[cclauss](@cclauss),[Sandhya Saravanan](@sandy9999)
lcm:[Rohit Tanwar](@kriadmin)
max_n:[Rohit Tanwar](@kriadmin)
min_n:[Rohit Tanwar](@kriadmin)
shuffle:[Rohit Tanwar](@kriadmin)
spread:[Rohit Tanwar](@kriadmin)
zip:[Rohit Tanwar](@kriadmin),[Leonardo Galdino](@LeonardoGaldino)
byte_size:[Rohit Tanwar](@kriadmin)
capitalize:[Rohit Tanwar](@kriadmin)
capitalize_every_word:[Rohit Tanwar](@kriadmin)
decapitalize:[Rohit Tanwar](@kriadmin)
palindrome:[Rohit Tanwar](@kriadmin)
is_upper_case:[Rohit Tanwar](@kriadmin)
is_lower_case:[Rohit Tanwar](@kriadmin)
count_by:[Rohit Tanwar](@kriadmin)
insertion_sort:[Meet Zaveri](@meetzaveri),[Rohit Tanwar](@kriadmin)
difference_by:[Rohit Tanwar](@kriadmin)
bubble_sort: [Shobhit Sachan](@sachans)
has_duplicates: [Rob-Rychs](@Rob-Rychs)
keys_only: [Rob-Rychs](@Rob-Rychs),[Matteo Veraldi](@mattveraldi)
values_only: [Rob-Rychs](@Rob-Rychs)
all_unique: [Rob-Rychs](@Rob-Rychs)
fibonacci_until_num: [Nian Lee](@scraggard)
fermat_test: [Alexander Pozdniakov](@0awawa0)

8
gatsby-browser.js Normal file
View File

@ -0,0 +1,8 @@
/**
* Implement Gatsby's Browser APIs in this file.
*
* See: https://www.gatsbyjs.org/docs/browser-apis/
*/
// You can delete this file if you're not using it
export { default as wrapRootElement } from './src/docs/state/ReduxWrapper';

82
gatsby-config.js Normal file
View File

@ -0,0 +1,82 @@
const config = require('./config');
module.exports = {
siteMetadata: {
title: `${config.name}`,
description: `${config.description}`,
author: `@30-seconds`,
},
plugins: [
`gatsby-plugin-transition-link`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `snippets`,
path: `${__dirname}/${config.snippetPath}`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `snippet_data`,
path: `${__dirname}/${config.snippetDataPath}`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `assets`,
path: `${__dirname}/${config.assetPath}`,
},
},
{
resolve: `gatsby-plugin-page-creator`,
options: {
path: `${__dirname}/${config.pagePath}`,
},
},
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 590,
},
},
`gatsby-remark-prismjs`,
`gatsby-remark-copy-linked-files`,
],
},
},
`gatsby-plugin-sass`,
`gatsby-transformer-json`,
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-plugin-google-analytics`,
options: {
trackingId: `UA-117141635-1`,
anonymize: true, // Always set this to true, try to comply with GDPR out of the box
respectDNT: true, // Always set to true, be respectful of people who ask not to be tracked
cookieExpires: 0, // Always set to 0, minimum tracking for your users
},
},
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `${config.name}`,
short_name: `${config.shortName}`,
start_url: `/`,
background_color: `#1e253d`,
theme_color: `#1e253d`,
display: `standalone`,
icon: `assets/30s-icon.png`, // This path is relative to the root of the site.
},
},
`gatsby-plugin-offline`,
`gatsby-plugin-react-helmet`,
`gatsby-plugin-netlify`,
],
};

93
gatsby-node.js Normal file
View File

@ -0,0 +1,93 @@
const path = require(`path`);
const { createFilePath } = require(`gatsby-source-filesystem`);
const toKebabCase = str =>
str &&
str
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
.map(x => x.toLowerCase())
.join('-');
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions;
const snippetPage = path.resolve(`./src/docs/templates/SnippetPage.js`);
const tagPage = path.resolve(`./src/docs/templates/TagPage.js`);
return graphql(
`
{
allMarkdownRemark(
sort: { fields: [frontmatter___title], order: ASC }
limit: 1000
) {
edges {
node {
fields {
slug
}
frontmatter {
tags
}
fileAbsolutePath
}
}
}
}
`,
).then(result => {
if (result.errors) {
throw result.errors;
}
// Create individual snippet pages.
const snippets = result.data.allMarkdownRemark.edges;
snippets.forEach((post, index) => {
if (post.node.fileAbsolutePath.indexOf('README') !== -1)
return;
createPage({
path: `/snippet${post.node.fields.slug}`,
component: snippetPage,
context: {
slug: post.node.fields.slug,
},
});
});
// Create tag pages.
const tags = snippets.reduce((acc, post) => {
if (!post.node.frontmatter || !post.node.frontmatter.tags) return acc;
const primaryTag = post.node.frontmatter.tags.split(',')[0];
if (!acc.includes(primaryTag)) acc.push(primaryTag);
return acc;
}, []);
tags.forEach(tag => {
const tagPath = `/tag/${toKebabCase(tag)}/`;
const tagRegex = `/^\\s*${tag}/`;
createPage({
path: tagPath,
component: tagPage,
context: {
tag,
tagRegex,
},
});
});
return null;
});
};
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions;
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode });
createNodeField({
name: `slug`,
node,
value,
});
}
};

8
gatsby-ssr.js Normal file
View File

@ -0,0 +1,8 @@
/**
* Implement Gatsby's SSR (Server Side Rendering) APIs in this file.
*
* See: https://www.gatsbyjs.org/docs/ssr-apis/
*/
// You can delete this file if you're not using it
export { default as wrapRootElement } from './src/docs/state/ReduxWrapper';

BIN
icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 31 KiB

1
language_fix.py Normal file
View File

@ -0,0 +1 @@
print('This file is here only to tag the repository language. Do not delete, please!')

6
netlify.toml Normal file
View File

@ -0,0 +1,6 @@
[build]
publish = "public"
command = "npm run webber"
[build.environment]
YARN_VERSION = "1.9.4"
YARN_FLAGS = "--no-ignore-optional"

22435
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

72
package.json Normal file
View File

@ -0,0 +1,72 @@
{
"name": "30-seconds-of-python",
"version": "1.0.0",
"description": "A curated collection of useful Python snippets that you can understand in 30 seconds or less.",
"main": "config.js",
"scripts": {
"builder": "node ./scripts/build.js",
"extractor": "node ./scripts/extract.js",
"webber": "gatsby build",
"webber:dev": "gatsby develop",
"webber:serve": "gatsby serve"
},
"repository": {
"type": "git",
"url": "git+https://github.com/30-seconds/30-seconds-of-python.git"
},
"author": "Stefan Fejes (ns.fejes.stefan@gmail.com)",
"license": "CC0-1.0",
"bugs": {
"url": "https://github.com/30-seconds/30-seconds-of-pythong-code/issues"
},
"homepage": "https://github.com/30-seconds/30-seconds-of-python",
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.5.4",
"@babel/plugin-proposal-class-properties": "^7.5.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/preset-env": "^7.5.4",
"@babel/preset-react": "^7.0.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"eslint": "^5.16.0",
"front-matter": "^3.0.2",
"fs-extra": "^8.1.0",
"gatsby": "^2.12.0",
"gatsby-image": "^2.2.6",
"gatsby-plugin-google-analytics": "^2.1.6",
"gatsby-plugin-manifest": "^2.2.3",
"gatsby-plugin-netlify": "^2.1.3",
"gatsby-plugin-offline": "^2.2.4",
"gatsby-plugin-page-creator": "^2.1.5",
"gatsby-plugin-react-helmet": "^3.1.2",
"gatsby-plugin-sass": "^2.1.3",
"gatsby-plugin-sharp": "^2.2.7",
"gatsby-plugin-transition-link": "^1.12.4",
"gatsby-remark-copy-linked-files": "^2.1.3",
"gatsby-remark-images": "^3.1.6",
"gatsby-remark-prismjs": "^3.3.3",
"gatsby-source-filesystem": "^2.1.5",
"gatsby-transformer-json": "^2.2.2",
"gatsby-transformer-remark": "^2.6.6",
"gatsby-transformer-sharp": "^2.2.3",
"gsap": "^2.1.3",
"jest": "^24.9.0",
"kleur": "^3.0.3",
"markdown-builder": "^0.9.0",
"node-sass": "^4.12.0",
"prettier": "^1.18.2",
"prismjs": "^1.16.0",
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-copy-to-clipboard": "^5.0.1",
"react-css-transition-replace": "^3.0.3",
"react-dom": "^16.8.6",
"react-helmet": "^5.2.1",
"react-redux": "^7.1.0",
"redux": "^4.0.4",
"rollup": "^0.58.2",
"rollup-plugin-babel": "^4.0.3",
"rollup-plugin-babel-minify": "^4.0.0"
}
}

View File

@ -1,18 +0,0 @@
autopep8==1.3.3
cffi==1.11.4
click==6.7
emoji==0.4.5
flake8==3.6.0
Flask==1.0
Flask-OAuth==0.12
gunicorn==19.7.1
httplib2==0.10.3
itsdangerous==0.24
Jinja2==2.10
MarkupSafe==1.0
misaka==2.1.0
mistune==0.8.3
oauth2==1.9.0.post1
pycodestyle==2.3.1
pycparser==2.18
Werkzeug==0.14.1

View File

@ -1,10 +0,0 @@
import autopep8
import os
import util
snippets = util.read_snippets()
for snippet in snippets:
formatedCode = autopep8.fix_code(snippet.read_code()).strip()
fixedCode = snippet.content.replace(snippet.read_code(),formatedCode)
snippetFile = open(f"snippets/{snippet.name}.md",'w')
snippetFile.write(fixedCode)
snippetFile.close()

137
scripts/build.js Normal file
View File

@ -0,0 +1,137 @@
/*
This is the builder script that generates the README file.
Run using `npm run builder`.
*/
// Load modules
const fs = require('fs-extra');
const path = require('path');
const { green, red } = require('kleur');
const util = require('./util');
const markdown = require('markdown-builder');
const { headers, misc, lists } = markdown;
const config = require('../config');
// Paths (relative to package.json)
const SNIPPETS_PATH = `./${config.snippetPath}`;
const STATIC_PARTS_PATH = `./${config.staticPartsPath}`;
// Terminate if parent commit is a Travis build
if (
util.isTravisCI() &&
/^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])
) {
console.log(
`${green(
'NOBUILD',
)} README build terminated, parent commit is a Travis build!`,
);
process.exit(0);
}
// Setup everything
let snippets = {},
snippetsArray = [],
startPart = '',
endPart = '',
output = '';
const EMOJIS = {};
console.time('Builder');
// Synchronously read all snippets from snippets folder and sort them as necessary (case-insensitive)
snippets = util.readSnippets(SNIPPETS_PATH);
snippetsArray = Object.keys(snippets).reduce((acc, key) => {
acc.push(snippets[key]);
return acc;
}, []);
// Load static parts for the README file
try {
startPart = fs.readFileSync(
path.join(STATIC_PARTS_PATH, 'README-start.md'),
'utf8',
);
endPart = fs.readFileSync(
path.join(STATIC_PARTS_PATH, 'README-end.md'),
'utf8',
);
} catch (err) {
console.log(`${red('ERROR!')} During static part loading: ${err}`);
process.exit(1);
}
// Create the output for the README file
try {
const tags = util.prepTaggedData(
Object.keys(snippets).reduce((acc, key) => {
acc[key] = snippets[key].attributes.tags;
return acc;
}, {}),
);
output += `${startPart}\n`;
// Loop over tags and snippets to create the table of contents
for (const tag of tags) {
const capitalizedTag = util.capitalize(tag, true);
const taggedSnippets = snippetsArray.filter(
snippet => snippet.attributes.tags[0] === tag,
);
output += headers.h3((EMOJIS[tag] || '') + ' ' + capitalizedTag).trim();
output +=
misc.collapsible(
'View contents',
lists.ul(taggedSnippets, snippet =>
misc.link(
`\`${snippet.title}\``,
`${misc.anchor(snippet.title)}${
snippet.attributes.tags.includes('advanced') ? '-' : ''
}`,
),
),
) + '\n';
}
for (const tag of tags) {
const capitalizedTag = util.capitalize(tag, true);
const taggedSnippets = snippetsArray.filter(
snippet => snippet.attributes.tags[0] === tag,
);
output +=
misc.hr() + headers.h2((EMOJIS[tag] || '') + ' ' + capitalizedTag) + '\n';
for (let snippet of taggedSnippets) {
if (snippet.attributes.tags.includes('advanced'))
output +=
headers.h3(
snippet.title + ' ' + misc.image('advanced', '/advanced.svg'),
) + '\n';
else output += headers.h3(snippet.title) + '\n';
output += snippet.attributes.text;
output += `\`\`\`${config.language}\n${snippet.attributes.codeBlocks.code}\n\`\`\``;
output += misc.collapsible(
'Examples',
`\`\`\`${config.language}\n${snippet.attributes.codeBlocks.example}\n\`\`\``,
);
output +=
'\n<br>' + misc.link('⬆ Back to top', misc.anchor('Contents')) + '\n';
}
}
// Add the ending static part
output += `\n${endPart}\n`;
// Write to the README file
fs.writeFileSync('README.md', output);
} catch (err) {
console.log(`${red('ERROR!')} During README generation: ${err}`);
process.exit(1);
}
console.log(`${green('SUCCESS!')} README file generated!`);
console.timeEnd('Builder');

80
scripts/extract.js Normal file
View File

@ -0,0 +1,80 @@
/*
This is the extractor script that generates the snippets.json file.
Run using `npm run extractor`.
*/
// Load modules
const fs = require('fs-extra');
const path = require('path');
const { green } = require('kleur');
const util = require('./util');
const config = require('../config');
// Paths (relative to package.json)
const SNIPPETS_PATH = `./${config.snippetPath}`;
const OUTPUT_PATH = `./${config.snippetDataPath}`;
// Check if running on Travis, only build for cron jobs and custom builds
if (
util.isTravisCI() &&
process.env['TRAVIS_EVENT_TYPE'] !== 'cron' &&
process.env['TRAVIS_EVENT_TYPE'] !== 'api'
) {
console.log(
`${green(
'NOBUILD',
)} snippet extraction terminated, not a cron or api build!`,
);
process.exit(0);
}
// Setup everything
let snippets = {},
snippetsArray = [];
console.time('Extractor');
// Synchronously read all snippets from snippets folder and sort them as necessary (case-insensitive)
snippets = util.readSnippets(SNIPPETS_PATH);
snippetsArray = Object.keys(snippets).reduce((acc, key) => {
acc.push(snippets[key]);
return acc;
}, []);
const completeData = {
data: [...snippetsArray],
meta: {
specification: 'http://jsonapi.org/format/',
type: 'snippetArray',
},
};
let listingData = {
data: completeData.data.map(v => ({
id: v.id,
type: 'snippetListing',
title: v.title,
attributes: {
text: v.attributes.text,
tags: v.attributes.tags,
},
meta: {
hash: v.meta.hash,
},
})),
meta: {
specification: 'http://jsonapi.org/format/',
type: 'snippetListingArray',
},
};
// Write files
fs.writeFileSync(
path.join(OUTPUT_PATH, 'snippets.json'),
JSON.stringify(completeData, null, 2),
);
fs.writeFileSync(
path.join(OUTPUT_PATH, 'snippetList.json'),
JSON.stringify(listingData, null, 2),
);
// Display messages and time
console.log(
`${green('SUCCESS!')} snippets.json and snippetList.json files generated!`,
);
console.timeEnd('Extractor');

View File

@ -1,10 +0,0 @@
import util
import subprocess
import sys
for snippet in util.read_snippets():
print(snippet.name)
code = snippet.read_code()
check_1 = subprocess.run(['flake8', '-','--select=E901,E999,F821,F822,F823','--count','--show-source','--statistics'], input=code, encoding='utf8',stdout=subprocess.PIPE)
check_2 = subprocess.run(['flake8', '-','--exit-zero','--max-complexity=10','--count','--max-line-length=127','--statistics','--ignore=W292'], input=code, encoding='utf8',stdout=subprocess.PIPE)
check_1.check_returncode()
check_2.check_returncode()

View File

@ -1,43 +0,0 @@
import util
from collections import defaultdict
def title_case(str):
return str[:1].upper() + str[1:].lower()
EMOJIS = {
'adapter': ':electric_plug:',
'list': ':books:',
'browser': ':globe_with_meridians:',
'date': ':stopwatch:',
'function': ':control_knobs:',
'logic': ':crystal_ball:',
'math': ':heavy_division_sign:',
'media': ':tv:',
'node': ':package:',
'object': ':card_file_box:',
'string': ':scroll:',
'type': ':page_with_curl:',
'utility': ':wrench:'
}
def tagger():
tag_db = defaultdict(list)
for snippet in util.read_snippets():
tag_db[snippet.category[0]].append(snippet)
return tag_db
start = util.read_readme_start()
end = util.read_readme_end()
toAppend = ''
tag_dict = tagger()
author_database = util.author_reader()
for category in sorted(tag_dict):
toAppend = toAppend + '### ' + EMOJIS[category] + ' ' + title_case(category) +'\n\n<details><summary>View contents</summary> <ul>'
for snippet in sorted(tag_dict[category],key=lambda snippet : snippet.name):
toAppend += f'<li><a href = "#{snippet.name}"><code>{snippet.name}</code></a></li>\n'
toAppend += '</ul></details>\n\n'
toAppend += '<hr></hr> \n\n'
for category in sorted(tag_dict):
toAppend = toAppend + '## ' + EMOJIS[category] + ' ' + title_case(category) +'\n\n'
for snippet in sorted(tag_dict[category],key=lambda snippet : snippet.name):
author,contributors = author_database[snippet.name]
contributors = ', '.join(contributors)
toAppend += f'### {snippet.name} \n<span style="color:grey">Author:-</span> {author} \n\n <span style="color:grey">Contributors:-</span>{contributors}\n\n{snippet.read_description()}\n```py\n{snippet.read_code()}\n```\n<details><summary>View Examples</summary>\n\n```py\n{snippet.read_example()}\n```\n</details>\n\n<br><a href = "#table-of-contents">:arrow_up: Back to top</a>\n\n'
open("README.md",'w').write(start+toAppend+'\n'+end)

View File

@ -1,22 +0,0 @@
import os,util
snippets = util.read_snippets()
for snippet in snippets:
os.makedirs('test/' + snippet.name,exist_ok=True)
file_to_write_to = open(f'test/{snippet.name}/{snippet.name}.py','w')
file_to_write_to.write(snippet.read_code())
file_to_write_to.close()
if not os.path.isfile(f'test/{snippet.name}/{snippet.name}.test.py'):
test_file = open(f'test/{snippet.name}/{snippet.name}.test.py','w')
test_file.write(f'''
import types,functools
from pytape import test
from {snippet.name} import {snippet.name}
def {snippet.name}_test(t):
t.true(isinstance({snippet.name}, (types.BuiltinFunctionType, types.FunctionType, functools.partial)),'{snippet} is a function')
test('Testing {snippet.name}',{snippet.name}_test)
'''.strip())
test_file.close()
else:
pass

View File

@ -1,67 +0,0 @@
import os,re
def author_reader():
contributor_file = open('contributor_database')
author_database = {}
contributor_db = contributor_file.read().split('\n')
contributor_db = [contributor for contributor in contributor_db if contributor.strip() != '']
for contributor_data_db in contributor_db:
snippetName,contributor_data = contributor_data_db.split(':')
author = contributor_data.split(',')[0]
contributors = contributor_data.split(',')
author = re.sub('(\[[\w\s]+\]\()\@(\w+)\)','\g<1>https://www.github.com/\g<2>)',author.strip())
contributors = [re.sub('(\[[\w\s]+\]\()\@(\w+)\)','\g<1>https://www.github.com/\g<2>)',contributor) for contributor in contributors]
author_database[snippetName] = (author,contributors)
return author_database
def tagger():
tag_database_file = open('tag_database')
tag_database = tag_database_file.read()
tag_database_file.close()
tag_database = [tag for tag in tag_database.split('\n') if tag.strip() != '']
tag_db = {}
for tag in tag_database:
tag_db[tag.split(':')[0].strip()] = tag.split(':')[1].strip().split(',')
return tag_db
def read_snippets():
snippet_files = os.listdir('snippets')
snippets = []
class snippet():
def __init__(self,file_location):
with open(file_location) as f:
self.content = f.read()
self.codeRe = "```\s*python([\s\S]*?)```"
self.titleRe = '###\\s*([\\w]+)'
self.descRe = '###\s*\w+\s*([\s\S]+)```\s*python[\s\S]+```\s*```\s*python[\s\S]+```'
self.name = self.read_title()
self.category = tagger()[self.name]
def read_code(self):
return re.findall(self.codeRe,self.content)[0].strip()
def read_title(self):
return re.findall(self.titleRe,self.content)[0].strip()
def read_description(self):
return re.findall(self.descRe,self.content)[0].strip()
def read_example(self):
return re.findall(self.codeRe,self.content)[1].strip()
for snippet_file in snippet_files:
snippets.append(snippet(f'snippets/{snippet_file}'))
return snippets
def read_readme_start():
with open('static-parts/readme-start.md') as f:
readme_start = f.read()
return readme_start
def read_readme_end():
with open('static-parts/readme-end.md') as f:
readme_end = f.read()
return readme_end

View File

@ -0,0 +1,12 @@
// Checks if current environment is Travis CI, Cron builds, API builds
const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env;
const isTravisCronOrAPI = () =>
process.env['TRAVIS_EVENT_TYPE'] === 'cron' ||
process.env['TRAVIS_EVENT_TYPE'] === 'api';
const isNotTravisCronOrAPI = () => !isTravisCronOrAPI();
module.exports = {
isTravisCI,
isTravisCronOrAPI,
isNotTravisCronOrAPI,
};

60
scripts/util/helpers.js Normal file
View File

@ -0,0 +1,60 @@
const config = require('../../config');
const getMarkDownAnchor = paragraphTitle =>
paragraphTitle
.trim()
.toLowerCase()
.replace(/[^\w\- ]+/g, '')
.replace(/\s/g, '-')
.replace(/\-+$/, '');
// Creates an object from pairs
const objectFromPairs = arr => arr.reduce((a, v) => ((a[v[0]] = v[1]), a), {});
// Optimizes nodes in an HTML document
const optimizeNodes = (data, regexp, replacer) => {
let count = 0;
let output = data;
do {
output = output.replace(regexp, replacer);
count = 0;
while (regexp.exec(output) !== null) ++count;
} while (count > 0);
return output;
};
// Capitalizes the first letter of a string
const capitalize = (str, lowerRest = false) =>
str.slice(0, 1).toUpperCase() +
(lowerRest ? str.slice(1).toLowerCase() : str.slice(1));
const prepTaggedData = tagDbData =>
[...new Set(Object.entries(tagDbData).map(t => t[1][0]))]
.filter(v => v)
.sort((a, b) =>
capitalize(a, true) === 'Uncategorized'
? 1
: capitalize(b, true) === 'Uncategorized'
? -1
: a.localeCompare(b),
);
const makeExamples = data => {
data =
data.slice(0, data.lastIndexOf(`\`\`\`${config.language}`)).trim() +
misc.collapsible(
'Examples',
data.slice(
data.lastIndexOf(`\`\`\`${config.language}`),
data.lastIndexOf('```'),
) + data.slice(data.lastIndexOf('```')),
);
return `${data}\n<br>${misc.link(
'⬆ Back to top',
misc.anchor('Contents'),
)}\n\n`;
};
module.exports = {
getMarkDownAnchor,
objectFromPairs,
optimizeNodes,
capitalize,
prepTaggedData,
makeExamples,
};

37
scripts/util/index.js Normal file
View File

@ -0,0 +1,37 @@
const {
isTravisCI,
isTravisCronOrAPI,
isNotTravisCronOrAPI,
} = require('./environmentCheck');
const {
getMarkDownAnchor,
objectFromPairs,
optimizeNodes,
capitalize,
prepTaggedData,
makeExamples,
} = require('./helpers');
const {
getFilesInDir,
hashData,
getCodeBlocks,
getTextualContent,
readSnippets,
} = require('./snippetParser');
module.exports = {
isTravisCI,
isTravisCronOrAPI,
isNotTravisCronOrAPI,
getMarkDownAnchor,
objectFromPairs,
optimizeNodes,
capitalize,
prepTaggedData,
makeExamples,
getFilesInDir,
hashData,
getCodeBlocks,
getTextualContent,
readSnippets,
};

View File

@ -0,0 +1,118 @@
const fs = require('fs-extra'),
path = require('path'),
{ red } = require('kleur'),
crypto = require('crypto'),
frontmatter = require('front-matter');
const config = require('../../config');
// Reade all files in a directory
const getFilesInDir = (directoryPath, withPath, exclude = null) => {
try {
let directoryFilenames = fs.readdirSync(directoryPath);
directoryFilenames.sort((a, b) => {
a = a.toLowerCase();
b = b.toLowerCase();
if (a < b) return -1;
if (a > b) return 1;
return 0;
});
if (withPath) {
// a hacky way to do conditional array.map
return directoryFilenames.reduce((fileNames, fileName) => {
if (
exclude == null ||
!exclude.some(toExclude => fileName === toExclude)
)
fileNames.push(`${directoryPath}/${fileName}`);
return fileNames;
}, []);
}
return directoryFilenames.filter(v => v !== 'README.md');
} catch (err) {
console.log(`${red('ERROR!')} During snippet loading: ${err}`);
process.exit(1);
}
};
// Creates a hash for a value using the SHA-256 algorithm.
const hashData = val =>
crypto
.createHash('sha256')
.update(val)
.digest('hex');
// Gets the code blocks for a snippet file.
const getCodeBlocks = str => {
const regex = /```[.\S\s]*?```/g;
let results = [];
let m = null;
while ((m = regex.exec(str)) !== null) {
if (m.index === regex.lastIndex) regex.lastIndex += 1;
m.forEach((match, groupIndex) => {
results.push(match);
});
}
const replacer = new RegExp(
`\`\`\`${config.language}([\\s\\S]*?)\`\`\``,
'g',
);
results = results.map(v => v.replace(replacer, '$1').trim());
return {
code: results[0],
example: results[1],
};
};
// Gets the textual content for a snippet file.
const getTextualContent = str => {
const regex = /([\s\S]*?)```/g;
const results = [];
let m = null;
while ((m = regex.exec(str)) !== null) {
if (m.index === regex.lastIndex) regex.lastIndex += 1;
m.forEach((match, groupIndex) => {
results.push(match);
});
}
return results[1].replace(/\r\n/g, '\n');
};
// Synchronously read all snippets and sort them as necessary (case-insensitive)
const readSnippets = snippetsPath => {
const snippetFilenames = getFilesInDir(snippetsPath, false);
let snippets = {};
try {
for (let snippet of snippetFilenames) {
let data = frontmatter(
fs.readFileSync(path.join(snippetsPath, snippet), 'utf8'),
);
snippets[snippet] = {
id: snippet.slice(0, -3),
title: data.attributes.title,
type: 'snippet',
attributes: {
fileName: snippet,
text: getTextualContent(data.body),
codeBlocks: getCodeBlocks(data.body),
tags: data.attributes.tags.split(',').map(t => t.trim()),
},
meta: {
hash: hashData(data.body),
},
};
}
} catch (err) {
console.log(`${red('ERROR!')} During snippet loading: ${err}`);
process.exit(1);
}
return snippets;
};
module.exports = {
getFilesInDir,
hashData,
getCodeBlocks,
getTextualContent,
readSnippets,
};

File diff suppressed because it is too large Load Diff

1509
snippet_data/snippets.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,18 @@
### function_name
---
title: function_name
tags: utility,intermediate
---
Describe briefly what the function does
Explain briefly what the snippet does.
Explain your method and the functions used.
Explain briefly how the snippet works.
``` python
```py
def function_name(args):
# code
return 0
# code
return 0
```
``` python
```py
function_name(val) # result
```

18
snippets/all_equal.md Normal file
View File

@ -0,0 +1,18 @@
---
title: all_equal
tags: list,beginner
---
Check if all elements in a list are equal.
Use `[1:]` and `[:-1]` to compare all the values in the given list.
```py
def all_equal(lst):
return lst[1:] == lst[:-1]
```
```py
all_equal([1, 2, 3, 4, 5, 6]) # False
all_equal([1, 1, 1, 1]) # True
```

View File

@ -1,15 +1,18 @@
### all_unique
---
title: all_unique
tags: list,beginner
---
Checks a flat list for all unique values. Returns True if list values are all unique and False if list values aren't all unique.
Returns `True` if all the values in a flat list are unique, `False` otherwise.
This function compares the length of the list with length of the set() of the list. set() removes duplicate values from the list.
Use `set()` on the given list to remove duplicates, compare its length with the length of the list.
``` python
```py
def all_unique(lst):
return len(lst) == len(set(lst))
return len(lst) == len(set(lst))
```
``` python
```py
x = [1,2,3,4,5,6]
y = [1,2,2,3,4,5]
all_unique(x) # True

View File

@ -1,17 +1,18 @@
### average
:information_source: Already implemented via `statistics.mean`. `statistics.mean` takes an array as an argument whereas this function takes variadic arguments.
---
title: average
tags: math,list,beginner
---
Returns the average of two or more numbers.
Takes the sum of all the `args` and divides it by `len(args)`. The second argument `0.0` in sum is to handle floating point division in `python3`.
Use `sum()` to sum all of the `args` provided, divide by `len(args)`.
```python
```py
def average(*args):
return sum(args, 0.0) / len(args)
return sum(args, 0.0) / len(args)
```
``` python
```py
average(*[1, 2, 3]) # 2.0
average(1, 2, 3) # 2.0
```

18
snippets/average_by.md Normal file
View File

@ -0,0 +1,18 @@
---
title: average_by
tags: math,list,function,intermediate
---
Returns the average of a list, after mapping each element to a value using the provided function.
Use `map()` to map each element to the value returned by `fn`.
Use `sum()` to sum all of the mapped values, divide by `len(lst)`.
```py
def average_by(lst, fn=lambda x: x):
return sum(map(fn, lst), 0.0) / len(lst)
```
```py
average_by([{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }], lambda x: x['n']) # 5.0
```

21
snippets/bifurcate.md Normal file
View File

@ -0,0 +1,21 @@
---
title: bifurcate
tags: list,intermediate
---
Splits values into two groups.
If an element in `filter` is `True`, the corresponding element in the collection belongs to the first group; otherwise, it belongs to the second group.
Use list comprehension and `enumerate()` to add elements to groups, based on `filter`.
```py
def bifurcate(lst, filter):
return [
[x for i,x in enumerate(lst) if filter[i] == True],
[x for i,x in enumerate(lst) if filter[i] == False]
]
```
```py
bifurcate(['beep', 'boop', 'foo', 'bar'], [True, True, False, True]) # [ ['beep', 'boop', 'bar'], ['foo'] ]
```

21
snippets/bifurcate_by.md Normal file
View File

@ -0,0 +1,21 @@
---
title: bifurcate_by
tags: list,function,intermediate
---
Splits values into two groups according to a function, which specifies which group an element in the input list belongs to.
If the function returns `True`, the element belongs to the first group; otherwise, it belongs to the second group.
Use list comprehension to add elements to groups, based on `fn`.
```py
def bifurcate_by(lst, fn):
return [
[x for x in lst if fn(x)],
[x for x in lst if not fn(x)]
]
```
```py
bifurcate_by(['beep', 'boop', 'foo', 'bar'], lambda x: x[0] == 'b') # [ ['beep', 'boop', 'bar'], ['foo'] ]
```

View File

@ -1,17 +0,0 @@
### bubble_sort
Bubble_sort uses the technique of comparing and swapping
```python
def bubble_sort(lst):
for passnum in range(len(lst) - 1, 0, -1):
for i in range(passnum):
if lst[i] > lst[i + 1]:
lst[i], lst[i + 1] = lst[i + 1], lst[i]
```
```python
lst = [54,26,93,17,77,31,44,55,20]
bubble_sort(lst)
print("sorted %s" %lst) # [17,20,26,31,44,54,55,77,91]
```

View File

@ -1,15 +1,18 @@
### byte_size
---
title: byte_size
tags: string, beginner
---
Returns the length of a string in bytes.
`utf-8` encodes a given string, then `len` finds the length of the encoded string.
Use `string.encode('utf-8')` to encode the given string and return its length.
```python
```py
def byte_size(string):
return(len(string.encode('utf-8')))
return len(string.encode('utf-8'))
```
```python
```py
byte_size('😀') # 4
byte_size('Hello World') # 11
```

26
snippets/camel.md Normal file
View File

@ -0,0 +1,26 @@
---
title: camel
tags: string,regexp,intermediate
---
Converts a string to camelcase.
Break the string into words and combine them capitalizing the first letter of each word, using a regexp.
```py
import re
def camel(str):
s = re.sub(r"(\s|_|-)+","",
re.sub(r"[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+",
lambda mo: mo.group(0)[0].upper() + mo.group(0)[1:].lower(),str)
)
return s[0].lower() + s[1:]
```
```py
camel('some_database_field_name'); # 'someDatabaseFieldName'
camel('Some label that needs to be camelized'); # 'someLabelThatNeedsToBeCamelized'
camel('some-javascript-property'); # 'someJavascriptProperty'
camel('some-mixed_string with spaces_underscores-and-hyphens'); # 'someMixedStringWithSpacesUnderscoresAndHyphens'
```

View File

@ -1,15 +1,19 @@
### capitalize
---
title: capitalize
tags: string,intermediate
---
Capitalizes the first letter of a string.
Capitalizes the first letter of the string and then adds it with rest of the string. Omit the `lower_rest` parameter to keep the rest of the string intact, or set it to `true` to convert to lowercase.
Capitalize the first letter of the string and then add it with rest of the string.
Omit the `lower_rest` parameter to keep the rest of the string intact, or set it to `True` to convert to lowercase.
```python
```py
def capitalize(string, lower_rest=False):
return string[:1].upper() + (string[1:].lower() if lower_rest else string[1:])
return string[:1].upper() + (string[1:].lower() if lower_rest else string[1:])
```
```python
```py
capitalize('fooBar') # 'FooBar'
capitalize('fooBar', True) # 'Foobar'
```

View File

@ -1,14 +1,17 @@
### capitalize_every_word
---
title: capitalize_every_word
tags: string,beginner
---
Capitalizes the first letter of every word in a string.
Uses `str.title` to capitalize first letter of every word in the string.
Use `string.title()` to capitalize first letter of every word in the string.
```python
```py
def capitalize_every_word(string):
return string.title()
return string.title()
```
```python
```py
capitalize_every_word('hello world!') # 'Hello World!'
```

18
snippets/cast_list.md Normal file
View File

@ -0,0 +1,18 @@
---
title: cast_list
tags: utility,list,beginner
---
Casts the provided value as an array if it's not one.
Use `isinstance()` to check if the given value is a list and return it as-is or encapsulated in a list accordingly.
```py
def cast_list(val):
return val if isinstance(val, list) else [val]
```
```py
cast_list('foo'); # ['foo']
cast_list([1]); # [1]
```

View File

@ -1,19 +1,23 @@
### chunk
---
title: chunk
tags: list,intermediate
---
Chunks an list into smaller lists of a specified size.
Chunks a list into smaller lists of a specified size.
Uses `range` to create a list of desired size. Then use `map` on this list and fill it with splices of `lst`.
Use `list()` and `range()` to create a list of the desired `size`.
Use `map()` on the list and fill it with splices of the given list.
Finally, return use created list.
```python
```py
from math import ceil
def chunk(lst, size):
return list(
map(lambda x: lst[x * size:x * size + size],
list(range(0, ceil(len(lst) / size)))))
return list(
map(lambda x: lst[x * size:x * size + size],
list(range(0, ceil(len(lst) / size)))))
```
``` python
```py
chunk([1,2,3,4,5],2) # [[1,2],[3,4],5]
```

19
snippets/clamp_number.md Normal file
View File

@ -0,0 +1,19 @@
---
title: clamp_number
tags: math,beginner
---
Clamps `num` within the inclusive range specified by the boundary values `a` and `b`.
If `num` falls within the range, return `num`.
Otherwise, return the nearest number in the range.
```py
def clamp_number(num,a,b):
return max(min(num, max(a,b)),min(a,b))
```
```py
clamp_number(2, 3, 5) # 3
clamp_number(1, -1, -5) # -1
```

View File

@ -1,14 +1,17 @@
### compact
---
title: compact
tags: list,beginner
---
Removes falsey values from a list.
Use `filter()` to filter out falsey values (False, None, 0, and "").
Use `filter()` to filter out falsey values (`False`, `None`, `0`, and `""`).
```python
```py
def compact(lst):
return list(filter(bool, lst))
return list(filter(bool, lst))
```
``` python
```py
compact([0, 1, False, 2, '', 3, 'a', 's', 34]) # [ 1, 2, 3, 'a', 's', 34 ]
```

View File

@ -1,21 +1,23 @@
### count_by
:information_source: Already implemented via `collections.Counter`
---
title: count_by
tags: list,intermediate
---
Groups the elements of a list based on the given function and returns the count of elements in each group.
Use `map()` to map the values of the list using the given function. Iterate over the map and increase the the elements count each time it occurs.
Use `map()` to map the values of the given list using the given function.
Iterate over the map and increase the element count each time it occurs.
```python
```py
def count_by(arr, fn=lambda x: x):
key = {}
for el in map(fn, arr):
key[el] = 0 if el not in key else key[el]
key[el] += 1
return key
key = {}
for el in map(fn, arr):
key[el] = 0 if el not in key else key[el]
key[el] += 1
return key
```
``` python
```py
from math import floor
count_by([6.1, 4.2, 6.3], floor) # {4: 1, 6: 2}
count_by(['one', 'two', 'three'], len) # {3: 2, 5: 1}

View File

@ -1,16 +1,17 @@
### count_occurences
:information_source: Already implemented via `list.count()`.
---
title: count_occurences
tags: list,beginner
---
Counts the occurrences of a value in a list.
Uses the list comprehension to increment a counter each time you encounter the specific value inside the list.
Increment a counter for every item in the list that has the given value and is of the same type.
```python
```py
def count_occurrences(lst, val):
return len([x for x in lst if x == val and type(x) == type(val)])
return len([x for x in lst if x == val and type(x) == type(val)])
```
```python
```py
count_occurrences([1, 1, 2, 1, 2, 3], 1) # 3
```

View File

@ -1,15 +0,0 @@
### count_vowels
Retuns `number` of vowels in provided `string`.
Use a regular expression to count the number of vowels `(A, E, I, O, U)` in a string.
```python
import re
def count_vowels(str):
return len(re.findall(r'[aeiou]', str, re.IGNORECASE))
count_vowels('foobar') # 3
count_vowels('gym')# 0
```

View File

@ -1,15 +1,19 @@
### decapitalize
---
title: decapitalize
tags: string,intermediate
---
Decapitalizes the first letter of a string.
Decapitalizes the first letter of the string and then adds it with rest of the string. Omit the `upper_rest` parameter to keep the rest of the string intact, or set it to `true` to convert to uppercase.
Decapitalize the first letter of the string and then add it with rest of the string.
Omit the `upper_rest` parameter to keep the rest of the string intact, or set it to `True` to convert to uppercase.
```python
```py
def decapitalize(string, upper_rest=False):
return str[:1].lower() + (str[1:].upper() if upper_rest else str[1:])
return str[:1].lower() + (str[1:].upper() if upper_rest else str[1:])
```
```python
```py
decapitalize('FooBar') # 'fooBar'
decapitalize('FooBar', True) # 'fOOBAR'
```

View File

@ -1,27 +1,32 @@
### deep_flatten
---
title: deep_flatten
tags: list,recursion,intermediate
---
Deep flattens a list.
Use recursion. Use `list.extend()` with an empty list (`result`) and the spread function to flatten a list. Recursively flatten each element that is a list.
Use recursion.
Define a function, `spread`, that uses either `list.extend()` or `list.append()` on each element in a list to flatten it.
Use `list.extend()` with an empty list and the `spread` function to flatten a list.
Recursively flatten each element that is a list.
```python
```py
def spread(arg):
ret = []
for i in arg:
if isinstance(i, list):
ret.extend(i)
else:
ret.append(i)
return ret
ret = []
for i in arg:
if isinstance(i, list):
ret.extend(i)
else:
ret.append(i)
return ret
def deep_flatten(lst):
result = []
result.extend(
spread(list(map(lambda x: deep_flatten(x) if type(x) == list else x, lst))))
return result
result = []
result.extend(
spread(list(map(lambda x: deep_flatten(x) if type(x) == list else x, lst))))
return result
```
```python
```py
deep_flatten([1, [2], [[3], 4], 5]) # [1,2,3,4,5]
```

View File

@ -1,14 +1,18 @@
### difference
---
title: difference
tags: list,beginner
---
Returns the difference between two iterables.
Use list comprehension to only keep values not contained in `b`.
Create a `set` from `b`, then use list comprehension on `a` to only keep values not contained in the previously created set, `_b`.
```python
```py
def difference(a, b):
_b = set(b)
return [item for item in a if item not in _b]
_b = set(b)
return [item for item in a if item not in _b]
```
``` python
```py
difference([1, 2, 3], [1, 2, 4]) # [3]
```

View File

@ -1,16 +1,19 @@
### difference_by
---
title: difference_by
tags: list,function,intermediate
---
Returns the difference between two list, after applying the provided function to each list element of both.
Returns the difference between two lists, after applying the provided function to each list element of both.
Create a `set` by applying `fn` to each element in `b`, then use list comprehension in combination with fn on a to only keep values not contained in the previously created `set`.
Create a `set` by applying `fn` to each element in `b`, then use list comprehension in combination with `fn` on `a` to only keep values not contained in the previously created set, `_b`.
```python
```py
def difference_by(a, b, fn):
b = set(map(fn, b))
return [item for item in a if fn(item) not in b]
_b = set(map(fn, b))
return [item for item in a if fn(item) not in _b]
```
```python
```py
from math import floor
difference_by([2.1, 1.2], [2.3, 3.4],floor) # [1.2]
difference_by([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], lambda v : v['x']) # [ { x: 2 } ]

17
snippets/digitize.md Normal file
View File

@ -0,0 +1,17 @@
---
title: digitize
tags: math,list,beginner
---
Converts a number to an array of digits.
Use `map()` combined with `int` on the string representation of `n` and return a list from the result.
```py
def digitize(n):
return list(map(int, str(n)))
```
```py
digitize(123) # [1, 2, 3]
```

22
snippets/every.md Normal file
View File

@ -0,0 +1,22 @@
---
title: every
tags: list,function,intermediate
---
Returns `True` if the provided function returns `True` for every element in the list, `False` otherwise.
Iterate over the elements of the list to test if every element in the list returns `True` based on `fn`.
Omit the seconds argument, `fn`, to check if all elements are `True`.
```py
def every(lst, fn=lambda x: not not x):
for el in lst:
if not fn(el):
return False
return True
```
```py
every([4, 2, 3], lambda x: x > 1) # True
every([1, 2, 3]) # True
```

17
snippets/every_nth.md Normal file
View File

@ -0,0 +1,17 @@
---
title: every_nth
tags: list,beginner
---
Returns every nth element in a list.
Use `[1::nth]` to create a new list that contains every nth element of the given list.
```py
def every_nth(lst, nth):
return lst[1::nth]
```
```py
every_nth([1, 2, 3, 4, 5, 6], 2) # [ 2, 4, 6 ]
```

View File

@ -1,16 +1,23 @@
### factorial
---
title: factorial
tags: math,recursion,beginner
---
Calculates the factorial of a number.
Use recursion. If `num` is less than or equal to `1`, return `1`. Otherwise, return the product of `num` and the factorial of `num - 1`. Throws an exception if `num` is a negative or a floating point number.
Use recursion.
If `num` is less than or equal to `1`, return `1`.
Otherwise, return the product of `num` and the factorial of `num - 1`.
Throws an exception if `num` is a negative or a floating point number.
```python
```py
def factorial(num):
if not ((num >= 0) & (num % 1 == 0)):
raise Exception(
f"Number( {num} ) can't be floating point or negative ")
return 1 if num == 0 else num * factorial(num - 1)
if not ((num >= 0) & (num % 1 == 0)):
raise Exception(
f"Number( {num} ) can't be floating point or negative ")
return 1 if num == 0 else num * factorial(num - 1)
```
``` python
```py
factorial(6) # 720
```

View File

@ -1,33 +0,0 @@
### fermat_test
Checks if the number is prime or not. Returns True if passed number is prime, and False if not.
The function uses Fermat's theorem.
First, it picks the number `A` in range `1`..`(n-1)`, then it checks if `A` to the power of `n-1` modulo `n` equals `1`.
If not, the number is not prime, else it's pseudoprime with probability 1/2. Applying this test `k `times we have probability `1/(2^k)`.
For example, if the number passes the test `10` times, we have probability `0.00098`.
``` python
from random import randint
def fermat_test(n, k=100):
if n <= 1:
return False
for i in range(k):
a = randint(1, n - 1)
if pow(a, n - 1, n) != 1:
return False
return True
```
``` python
fermat_test(0) # False
fermat_test(1) # False
fermat_test(561) # False
fermat_test(41041) # False
fermat_test(17) # True
fermat_test(162259276829213363391578010288127) # True
fermat_test(-1) # False
```

View File

@ -1,23 +1,26 @@
### fibonacci
---
title: fibonacci
tags: math,list,intermediate
---
Generates an array, containing the Fibonacci sequence, up until the nth term.
Starting with 0 and 1, adds the sum of the last two numbers of the list to the end of the list using ```list.append()``` until the length of the list reaches n. If the given nth value is 0 or less, the method will just return a list containing 0.
Starting with `0` and `1`, use `list.apoend() to add the sum of the last two numbers of the list to the end of the list, until the length of the list reaches `n`.
If `n` is less or equal to `0`, return a list containing `0`.
``` python
```py
def fibonacci(n):
if n <= 0:
return [0]
if n <= 0:
return [0]
sequence = [0, 1]
while len(sequence) <= n:
# Add the sum of the previous two numbers to the sequence
next_value = sequence[len(sequence) - 1] + sequence[len(sequence) - 2]
sequence.append(next_value)
sequence = [0, 1]
while len(sequence) <= n:
next_value = sequence[len(sequence) - 1] + sequence[len(sequence) - 2]
sequence.append(next_value)
return sequence
return sequence
```
``` python
```py
fibonacci(7) # [0, 1, 1, 2, 3, 5, 8, 13]
```

View File

@ -1,18 +0,0 @@
### fibonacci_until_num
Returns the n-th term in a Fibonnaci sequence that starts with 1
A term in a Fibonnaci sequence is the sum of the two previous terms.
This function recursively calls the function to find the n-th term.
``` python
def fibonacci_until_num(n):
if n < 3:
return 1
return fibonacci_until_num(n - 2) + fibonacci_until_num(n - 1)
```
``` python
fibonnaci_until_num(5) # 5
fibonnaci_until_num(15) # 610
```

View File

@ -0,0 +1,17 @@
---
title: filter_non_unique
tags: list,beginner
---
Filters out the non-unique values in a list.
Use list comprehension and `list.count()` to create a list containing only the unique values.
```py
def filter_non_unique(lst):
return [item for item in lst if lst.count(item) == 1]
```
```py
filter_non_unique([1, 2, 2, 3, 4, 4, 5]) # [1, 3, 5]
```

View File

@ -1,17 +1,20 @@
### gcd
---
title: gcd
tags: math,beginner
---
Calculates the greatest common divisor of a list of numbers.
Uses the reduce function from the inbuilt module `functools`. Also uses the `math.gcd` function over a list.
Use `reduce()` and `math.gcd` over the given list.
```python
```py
from functools import reduce
import math
def gcd(numbers):
return reduce(math.gcd, numbers)
return reduce(math.gcd, numbers)
```
``` python
```py
gcd([8,36,28]) # 4
```

23
snippets/group_by.md Normal file
View File

@ -0,0 +1,23 @@
---
title: group_by
tags: list,object,beginner
---
Groups the elements of a list based on the given function.
Use `list()` in combination with `map()` and `fn` to map the values of the list to the keys of an object.
Use list comprehension to map each element to the appropriate `key`.
```py
def group_by(lst, fn):
groups = {}
for key in list(map(fn,lst)):
groups[key] = [item for item in lst if fn(item) == key]
return groups
```
```py
import math
group_by([6.1, 4.2, 6.3], math.floor); # {4: [4.2], 6: [6.1, 6.3]}
group_by(['one', 'two', 'three'], 'length'); # {3: ['one', 'two'], 5: ['three']}
```

View File

@ -1,15 +1,18 @@
### has_duplicates
---
title: has_duplicates
tags: list,beginner
---
Checks a flat list for duplicate values. Returns True if duplicate values exist and False if values are all unique.
Returns `True` if there are duplicate values in a flast list, `False` otherwise.
This function compares the length of the list with length of the set() of the list. set() removes duplicate values from the list.
Use `set()` on the given list to remove duplicates, compare its length with the length of the list.
``` python
```py
def has_duplicates(lst):
return len(lst) != len(set(lst))
return len(lst) != len(set(lst))
```
``` python
```py
x = [1,2,3,4,5,5]
y = [1,2,3,4,5]
has_duplicates(x) # True

17
snippets/head.md Normal file
View File

@ -0,0 +1,17 @@
---
title: head
tags: list,beginner
---
Returns the head of a list.
use `lst[0]` to return the first element of the passed list.
```py
def head(lst):
return lst[0]
```
```py
head([1, 2, 3]); # 1
```

23
snippets/in_range.md Normal file
View File

@ -0,0 +1,23 @@
---
title: in_range
tags: math,beginner
---
Checks if the given number falls within the given range.
Use arithmetic comparison to check if the given number is in the specified range.
If the second parameter, `end`, is not specified, the range is considered to be from `0` to `start`.
```py
def in_range(n, start, end = 0):
if (start > end):
end, start = start, end
return start <= n <= end
```
```py
in_range(3, 2, 5); # True
in_range(3, 4); # True
in_range(2, 3, 5); # False
in_range(3, 2); # False
```

17
snippets/initial.md Normal file
View File

@ -0,0 +1,17 @@
---
title: initial
tags: list,beginner
---
Returns all the elements of a list except the last one.
Use `lst[0:-1]` to return all but the last element of the list.
```py
def initial(lst):
return lst[0:-1]
```
```py
initial([1, 2, 3]); # [1,2]
```

View File

@ -0,0 +1,20 @@
---
title: initialize_2d_list
tags: list,intermediate
---
Initializes a 2D list of given width and height and value.
Use list comprehension and `range()` to generate `h` rows where each is a list with length `h`, initialized with `val`.
If `val` is not provided, default to `None`.
Explain briefly how the snippet works.
```py
def initialize_2d_list(w,h, val = None):
return [[val for x in range(w)] for y in range(h)]
```
```py
initialize_2d_list(2, 2, 0) # [[0,0], [0,0]]
```

View File

@ -0,0 +1,21 @@
---
title: initialize_list_with_range
tags: list,beginner
---
Initializes a list containing the numbers in the specified range where `start` and `end` are inclusive with their common difference `step`.
Use list comprehension and `range()` to generate a list of the appropriate length, filled with the desired values in the given range.
Omit `start` to use the default value of `0`.
Omit `step` to use the default value of `1`.
```py
def initialize_list_with_range(end, start = 0, step = 1):
return [x for x in range(start, end + 1, step)]
```
```py
initialize_list_with_range(5) # [0, 1, 2, 3, 4, 5]
initialize_list_with_range(7,3) # [3, 4, 5, 6, 7]
initialize_list_with_range(9,0,2) # [0, 2, 4, 6, 8]
```

View File

@ -0,0 +1,18 @@
---
title: initialize_list_with_values
tags: list,beginner
---
Initializes and fills a list with the specified value.
Use list comprehension and `range()` to generate a list of length equal to `n`, filled with the desired values.
Omit `val` to use the default value of `0`.
```py
def initialize_list_with_values(n, val = 0):
return [val for x in range(n)]
```
```py
initialize_list_with_values(5, 2) # [2, 2, 2, 2, 2]
```

View File

@ -1,21 +0,0 @@
### insertion_sort
On a very basic level, an insertion sort algorithm contains the logic of shifting around and inserting elements in order to sort an unordered list of any size. The way that it goes about inserting elements, however, is what makes insertion sort so very interesting!
```python
def insertion_sort(lst):
for i in range(1, len(lst)):
key = lst[i]
j = i - 1
while j >= 0 and key < lst[j]:
lst[j + 1] = lst[j]
j -= 1
lst[j + 1] = key
```
```python
lst = [7,4,9,2,6,3]
insertionsort(lst)
print('Sorted %s' %lst) # sorted [2, 3, 4, 6, 7, 9]
```

18
snippets/intersection.md Normal file
View File

@ -0,0 +1,18 @@
---
title: intersection
tags: list,beginner
---
Returns a list of elements that exist in both lists.
Create a `set` from `b`, then use list comprehension on `a` to only keep values contained in both lists.
```py
def intersection(a, b):
_b = set(b)
return [item for item in a if item in _b]
```
```py
intersection([1, 2, 3], [4, 3, 2]) # [2, 3]
```

View File

@ -0,0 +1,19 @@
---
title: intersection_by
tags: list,function,intermediate
---
Returns a list of elements that exist in both lists, after applying the provided function to each list element of both.
Create a `set` by applying `fn` to each element in `b`, then use list comprehension in combination with `fn` on `a` to only keep values contained in both lists.
```py
def intersection_by(a, b, fn):
_b = set(map(fn, b))
return [item for item in a if fn(item) in _b]
```
```py
from math import floor
intersection_by([2.1, 1.2], [2.3, 3.4],floor) # [2.1]
```

View File

@ -1,20 +1,24 @@
### is_anagram
---
title: is_anagram
tags: string,intermediate
---
Determine if 2 strings are anagrams.
Checks if a string is an anagram of another string (case-insensitive, ignores spaces, punctuation and special characters).
Returns true if 2 strings are anagrams of each other, false otherwise.
Capital letters and whitespaces are ignored.
Use `str.replace()` to remove spaces from both strings.
Compare the lengths of the two strings, return `False` if they are not equal.
Use `sorted()` on both strings and compare the results.
``` python
```py
def is_anagram(str1, str2):
str1, str2 = str1.replace(" ", ""), str2.replace(" ", "")
_str1, _str2 = str1.replace(" ", ""), str2.replace(" ", "")
if len(str1) != len(str2):
return False
else:
return sorted(str1.lower()) == sorted(str2.lower())
if len(_str1) != len(_str2):
return False
else:
return sorted(_str1.lower()) == sorted(_str2.lower())
```
``` python
```py
is_anagram("anagram", "Nag a ram") # True
```

17
snippets/is_divisible.md Normal file
View File

@ -0,0 +1,17 @@
---
title: is_divisible
tags: math,beginner
---
Checks if the first numeric argument is divisible by the second one.
Use the modulo operator (`%`) to check if the remainder is equal to `0`.
```py
def is_divisible(dividend, divisor):
return dividend % divisor == 0
```
```py
is_divisible(6, 3) # True
```

18
snippets/is_even.md Normal file
View File

@ -0,0 +1,18 @@
---
title: is_even
tags: math,beginner
---
Returns `True` if the given number is even, `False` otherwise.
Checks whether a number is odd or even using the modulo (`%`) operator.
Returns `True` if the number is even, `False` if the number is odd.
```py
def is_even(num):
return num % 2 == 0
```
```py
is_even(3) # False
```

View File

@ -1,15 +1,18 @@
### is_lower_case
---
title: is_lower_case
tags: string,utility,beginner
---
Checks if a string is lower case.
Convert the given string to lower case, using `str.lower()` method and compare it to the original.
Convert the given string to lower case, using `str.lower()` and compare it to the original.
```python
```py
def is_lower_case(string):
return string == string.lower()
return string == string.lower()
```
```python
```py
is_lower_case('abc') # True
is_lower_case('a3@$') # True
is_lower_case('Ab4') # False

18
snippets/is_odd.md Normal file
View File

@ -0,0 +1,18 @@
---
title: is_odd
tags: math,beginner
---
Returns `True` if the given number is odd, `False` otherwise.
Checks whether a number is even or odd using the modulo (`%`) operator.
Returns `True` if the number is odd, `False` if the number is even.
```py
def is_odd(num):
return num % 2 == `0`
```
```py
is_odd(3) # True
```

View File

@ -1,15 +1,18 @@
### is_upper_case
---
title: is_upper_case
tags: string,utility,beginner
---
Checks if a string is upper case.
Convert the given string to upper case, using `str.upper()` method and compare it to the original.
Convert the given string to upper case, using `str.upper()` and compare it to the original.
```python
```py
def is_upper_case(string):
return string == string.upper()
return string == string.upper()
```
```python
```py
is_upper_case('ABC') # True
is_upper_case('a3@$') # False
is_upper_case('aB4') # False

25
snippets/kebab.md Normal file
View File

@ -0,0 +1,25 @@
---
title: kebab
tags: string,regexp,intermediate
---
Converts a string to kebab case.
Break the string into words and combine them adding `-` as a separator, using a regexp.
```py
import re
def kebab(str):
return re.sub(r"(\s|_|-)+","-",
re.sub(r"[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+",
lambda mo: mo.group(0).lower(),str)
)
```
```py
kebab('camelCase'); # 'camel-case'
kebab('some text'); # 'some-text'
kebab('some-mixed_string With spaces_underscores-and-hyphens'); # 'some-mixed-string-with-spaces-underscores-and-hyphens'
kebab('AllThe-small Things'); # "all-the-small-things"
```

View File

@ -1,19 +1,23 @@
### keys_only
---
title: keys_only
tags: object,list,beginner
---
Function which accepts a dictionary of key value pairs and returns a new flat list of only the keys.
Returns a flat list of all the keys in a flat dictionary.
Uses the .keys() method of "dict" objects. dict.keys() returns a view object that displays a list of all the keys. Then, list(dict.keys()) returns a list that stores all the keys of a dict.
Use `dict.keys()` to return the keys in the given dictionary.
Return a `list()` of the previous result.
``` python
```py
def keys_only(flat_dict):
return list(flat_dict.keys())
return list(flat_dict.keys())
```
``` python
```py
ages = {
"Peter": 10,
"Isabel": 11,
"Anna": 9,
"Peter": 10,
"Isabel": 11,
"Anna": 9,
}
keys_only(ages) # ['Peter', 'Isabel', 'Anna']
```

17
snippets/last.md Normal file
View File

@ -0,0 +1,17 @@
---
title: last
tags: list,beginner
---
Returns the last element in a list.
use `lst[-1]` to return the last element of the passed list.
```py
def last(lst):
return lst[-1]
```
```py
last([1, 2, 3]) # 3
```

Some files were not shown because too many files have changed in this diff Show More