diff --git a/README.md b/README.md index 0bdc058..1e0ab3e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,5 @@ # ForgeBox -> Data science comprehensive toolbox 🛠⚔️📦 - - -![forgebox logo](https://raw.githubusercontent.com/raynardj/forgebox/new_feature/docs/logo.jpg) +> Data science comprehensive toolbox ## Installation @@ -25,7 +22,7 @@ The following command will import many frequent tools for data science, like **p from frogebox.imports import * ``` -No more🚫 following typings +No more following verbosity ```python import pandas as pd import numpy as np @@ -33,82 +30,6 @@ import os import json ... ``` - -### Categorical converter - -> Mapping and converting categorical infomation - -```python -from forgebox.category import Category -``` - -```python -az = list(map(chr,range(ord("A"), ord("z")+1))) -print(az) -``` - - ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] - - -```python -cate_az = Category(az) -cate_az -``` - - - - - Category Manager with 58 - - - -```python -cate_az.c2i["R"], cate_az.i2c[17] -``` - - - - - (17, 'R') - - - -```python -cate_az.c2i[list("ForgeBox")] -``` - - - - - array([ 5, 46, 49, 38, 36, 1, 46, 55]) - - - -```python -cate_az.i2c[[ 5, 46, 49, 38, 36, 1, 46, 55]] -``` - - - - - array(['F', 'o', 'r', 'g', 'e', 'B', 'o', 'x'], dtype=' - @@ -187,37 +92,6 @@ file_detail("/Users/xiaochen.zhang/.cache/").sample(5) - -### JS style async - -```python -from forgebox.asyncing import Async -from time import sleep -``` - -```python -def something_time_costing_but_you_dont_want_to_wait(x): - sleep(x) - return f"slept for {x} seconds" - -def task2_you_will_perfrom_after_the_time_costing_one(x): - print(f"[result]:\t{x}") - return 1 - -print("1111111111") - -Async(something_time_costing_but_you_dont_want_to_wait)(2)\ -.then(task2_you_will_perfrom_after_the_time_costing_one)\ -.catch(print) - -print("22222222222") -``` - - 1111111111 - 22222222222 - [result]: slept for 2 seconds - - ### HTML in notebook ```python @@ -231,26 +105,6 @@ bands = ["police", "headpin", {"ac":"dc"}] list_group(bands)() ``` - - - - -```python -questions = { - "question":"answer", - "another":{ - "deeper question": "answer again"}, - "final":{ - "questions": ["what","is","the","answer", "to", - ["life", "universe","everything"]]} -} -list_group_kv(questions)() -``` - - - - - #### Coding html in python ```python @@ -271,23 +125,6 @@ ul() -### Free style mapping - -Works on every value of a complicated dictionary structure (eg. list in dict in list in dict, etc,. 😳) - -```python -from forgebox.freemap import FreeMap - -# flatten decides if we want to flatten the strucuture -freemap_tool = FreeMap( - , - , - flatten=True -) - -data2 = freemap_tool(data1) -``` - ### Interactive Widgets > Interactive widgets work with in jupyter notebooks @@ -306,32 +143,14 @@ search_box(data_df, columns=["col1","col2"], manual=False) You can browse through a pandas dataframe like fliping pages 📄. ```python -from forgebox.widgets import paginate - -paginate(your_dataframe, page_len=10) +# this will import many things like enhanced pandas +from forgebox.imports import * +df = pd.read_csv("xxxx.csv") +df.paginate() ``` -#### Single button callback -> a fully functional page with a single button, this single button is bonded to a function - -This is as much code as you need, to build a fully functional interactive page shows sql table from jupyter, that you can:* choose which table to visit* choose how many lines you want to show, (with a slider) -* configure the where condition with a text box on front end - ```python -tablename_list = ["pubmed", "patient", "users", "drugs"] - -from forgebox.html import DOM -def show_sql_table(sql_input:str) -> str: - with engine.connect() as conn: - df=pd.read_sql(sql_input, con=conn) - # display the table as html - DOM(df.to_html(),"div")() - -@SingleButton(callback=show_sql_table) -def abc( - limit:{"typing":int, "default":10, "min":5, "max":20}, - where_condition:{"typing":str, "default": "where 1=1", }, - table:{"typing":list, "options":tablename_list} -): - return f"SELECT * FROM {table} {where_condition} LIMIT {limit}" +from forgebox.widgets import paginate + +paginate(your_dataframe, page_len=10) ``` diff --git a/docs/.DS_Store b/docs/.DS_Store deleted file mode 100644 index 686779f..0000000 Binary files a/docs/.DS_Store and /dev/null differ diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 57510a2..0000000 --- a/docs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_site/ diff --git a/docs/CUDA_GPU_Management.html b/docs/CUDA_GPU_Management.html deleted file mode 100644 index 666e92e..0000000 --- a/docs/CUDA_GPU_Management.html +++ /dev/null @@ -1,185 +0,0 @@ ---- - -title: CUDA GPU Management - -keywords: fastai -sidebar: home_sidebar - -summary: "A handler on GPU management" ---- - - -
- {% raw %} - -
- -
-
-
-

Handler on a single CUDA device

-
-
-
-
-
-

This tool will find the CUDA info from the system, the most current info about

-
    -
  • How much is the total CUDA memory
  • -
  • How much will the CUDA memory is in use
  • -
  • How much CUDA memory is free
  • -
- -
-
-
-
- -
-
- -
-
- -
- - -
-

class CudaDevice[source]

CudaDevice(idx)

-
- -
- -
- -
-
- -
-
-
-

A handler managing multiple devices

-
-
-
-
- -
-
- -
-
- -
- - -
-

class CudaHandler[source]

CudaHandler()

-
- -
- -
- -
-
- -
-
-
-

Tutorial

-
-
-
-
-
-

These handler is to simplify the multi-cuda situation, where you can allocate the most idle GPU

- -
-
-
-
-
- -
-
-
from forgebox.ftorch.cuda import CudaHandler
-
- -
-
-
- -
-
-
-

Substantiate the handler

- -
-
-
-
-
- -
-
-
ch = CudaHandler()
-
- -
-
-
- -
-
-
-

Found the most idle device, by measure of CUDA memory

- -
-
-
-
-
- -
-
-
dev = ch.idle()()
-
- -
-
-
- -
-
-
-

How we use the device in pytorch coding

- -
-
-
-
-
- -
-
-
some_torch_tensor.to(dev)
-
- -
-
-
- -
- {% endraw %} -
- - diff --git a/docs/Gemfile b/docs/Gemfile deleted file mode 100644 index f09053c..0000000 --- a/docs/Gemfile +++ /dev/null @@ -1,7 +0,0 @@ -source "https://rubygems.org" - -gem 'github-pages', group: :jekyll_plugins - - -# Added at 2019-11-25 10:11:40 -0800 by jhoward: -gem "jekyll", "~> 3.7" diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock deleted file mode 100644 index 8d85bea..0000000 --- a/docs/Gemfile.lock +++ /dev/null @@ -1,252 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - activesupport (4.2.11.1) - i18n (~> 0.7) - minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) - tzinfo (~> 1.1) - addressable (2.7.0) - public_suffix (>= 2.0.2, < 5.0) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.11.1) - colorator (1.1.0) - commonmarker (0.17.13) - ruby-enum (~> 0.5) - concurrent-ruby (1.1.5) - dnsruby (1.61.3) - addressable (~> 2.5) - em-websocket (0.5.1) - eventmachine (>= 0.12.9) - http_parser.rb (~> 0.6.0) - ethon (0.12.0) - ffi (>= 1.3.0) - eventmachine (1.2.7) - execjs (2.7.0) - faraday (0.17.0) - multipart-post (>= 1.2, < 3) - ffi (1.11.3) - forwardable-extended (2.6.0) - gemoji (3.0.1) - github-pages (202) - activesupport (= 4.2.11.1) - github-pages-health-check (= 1.16.1) - jekyll (= 3.8.5) - jekyll-avatar (= 0.6.0) - jekyll-coffeescript (= 1.1.1) - jekyll-commonmark-ghpages (= 0.1.6) - jekyll-default-layout (= 0.1.4) - jekyll-feed (= 0.11.0) - jekyll-gist (= 1.5.0) - jekyll-github-metadata (= 2.12.1) - jekyll-mentions (= 1.4.1) - jekyll-optional-front-matter (= 0.3.0) - jekyll-paginate (= 1.1.0) - jekyll-readme-index (= 0.2.0) - jekyll-redirect-from (= 0.14.0) - jekyll-relative-links (= 0.6.0) - jekyll-remote-theme (= 0.4.0) - jekyll-sass-converter (= 1.5.2) - jekyll-seo-tag (= 2.5.0) - jekyll-sitemap (= 1.2.0) - jekyll-swiss (= 0.4.0) - jekyll-theme-architect (= 0.1.1) - jekyll-theme-cayman (= 0.1.1) - jekyll-theme-dinky (= 0.1.1) - jekyll-theme-hacker (= 0.1.1) - jekyll-theme-leap-day (= 0.1.1) - jekyll-theme-merlot (= 0.1.1) - jekyll-theme-midnight (= 0.1.1) - jekyll-theme-minimal (= 0.1.1) - jekyll-theme-modernist (= 0.1.1) - jekyll-theme-primer (= 0.5.3) - jekyll-theme-slate (= 0.1.1) - jekyll-theme-tactile (= 0.1.1) - jekyll-theme-time-machine (= 0.1.1) - jekyll-titles-from-headings (= 0.5.1) - jemoji (= 0.10.2) - kramdown (= 1.17.0) - liquid (= 4.0.0) - listen (= 3.1.5) - mercenary (~> 0.3) - minima (= 2.5.0) - nokogiri (>= 1.10.4, < 2.0) - rouge (= 3.11.0) - terminal-table (~> 1.4) - github-pages-health-check (1.16.1) - addressable (~> 2.3) - dnsruby (~> 1.60) - octokit (~> 4.0) - public_suffix (~> 3.0) - typhoeus (~> 1.3) - html-pipeline (2.12.2) - activesupport (>= 2) - nokogiri (>= 1.4) - http_parser.rb (0.6.0) - i18n (0.9.5) - concurrent-ruby (~> 1.0) - jekyll (3.8.5) - addressable (~> 2.4) - colorator (~> 1.0) - em-websocket (~> 0.5) - i18n (~> 0.7) - jekyll-sass-converter (~> 1.0) - jekyll-watch (~> 2.0) - kramdown (~> 1.14) - liquid (~> 4.0) - mercenary (~> 0.3.3) - pathutil (~> 0.9) - rouge (>= 1.7, < 4) - safe_yaml (~> 1.0) - jekyll-avatar (0.6.0) - jekyll (~> 3.0) - jekyll-coffeescript (1.1.1) - coffee-script (~> 2.2) - coffee-script-source (~> 1.11.1) - jekyll-commonmark (1.3.1) - commonmarker (~> 0.14) - jekyll (>= 3.7, < 5.0) - jekyll-commonmark-ghpages (0.1.6) - commonmarker (~> 0.17.6) - jekyll-commonmark (~> 1.2) - rouge (>= 2.0, < 4.0) - jekyll-default-layout (0.1.4) - jekyll (~> 3.0) - jekyll-feed (0.11.0) - jekyll (~> 3.3) - jekyll-gist (1.5.0) - octokit (~> 4.2) - jekyll-github-metadata (2.12.1) - jekyll (~> 3.4) - octokit (~> 4.0, != 4.4.0) - jekyll-mentions (1.4.1) - html-pipeline (~> 2.3) - jekyll (~> 3.0) - jekyll-optional-front-matter (0.3.0) - jekyll (~> 3.0) - jekyll-paginate (1.1.0) - jekyll-readme-index (0.2.0) - jekyll (~> 3.0) - jekyll-redirect-from (0.14.0) - jekyll (~> 3.3) - jekyll-relative-links (0.6.0) - jekyll (~> 3.3) - jekyll-remote-theme (0.4.0) - addressable (~> 2.0) - jekyll (~> 3.5) - rubyzip (>= 1.2.1, < 3.0) - jekyll-sass-converter (1.5.2) - sass (~> 3.4) - jekyll-seo-tag (2.5.0) - jekyll (~> 3.3) - jekyll-sitemap (1.2.0) - jekyll (~> 3.3) - jekyll-swiss (0.4.0) - jekyll-theme-architect (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-cayman (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-dinky (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-hacker (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-leap-day (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-merlot (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-midnight (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-minimal (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-modernist (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-primer (0.5.3) - jekyll (~> 3.5) - jekyll-github-metadata (~> 2.9) - jekyll-seo-tag (~> 2.0) - jekyll-theme-slate (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-tactile (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-time-machine (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-titles-from-headings (0.5.1) - jekyll (~> 3.3) - jekyll-watch (2.2.1) - listen (~> 3.0) - jemoji (0.10.2) - gemoji (~> 3.0) - html-pipeline (~> 2.2) - jekyll (~> 3.0) - kramdown (1.17.0) - liquid (4.0.0) - listen (3.1.5) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - ruby_dep (~> 1.2) - mercenary (0.3.6) - mini_portile2 (2.5.0) - minima (2.5.0) - jekyll (~> 3.5) - jekyll-feed (~> 0.9) - jekyll-seo-tag (~> 2.1) - minitest (5.13.0) - multipart-post (2.1.1) - nokogiri (1.11.2) - mini_portile2 (~> 2.5.0) - racc (~> 1.4) - octokit (4.14.0) - sawyer (~> 0.8.0, >= 0.5.3) - pathutil (0.16.2) - forwardable-extended (~> 2.6) - public_suffix (3.1.1) - racc (1.5.2) - rb-fsevent (0.10.3) - rb-inotify (0.10.0) - ffi (~> 1.0) - rouge (3.11.0) - ruby-enum (0.7.2) - i18n - ruby_dep (1.5.0) - rubyzip (2.0.0) - safe_yaml (1.0.5) - sass (3.7.4) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - sawyer (0.8.2) - addressable (>= 2.3.5) - faraday (> 0.8, < 2.0) - terminal-table (1.8.0) - unicode-display_width (~> 1.1, >= 1.1.1) - thread_safe (0.3.6) - typhoeus (1.3.1) - ethon (>= 0.9.0) - tzinfo (1.2.5) - thread_safe (~> 0.1) - unicode-display_width (1.6.0) - -PLATFORMS - ruby - -DEPENDENCIES - github-pages - jekyll (~> 3.7) - -BUNDLED WITH - 2.0.2 diff --git a/docs/Untitled.html b/docs/Untitled.html deleted file mode 100644 index 8604635..0000000 --- a/docs/Untitled.html +++ /dev/null @@ -1,66 +0,0 @@ ---- - -title: Title - -keywords: fastai -sidebar: home_sidebar - - - ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
from forgebox.imports import *
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
def learn_it(x,y,model):
-
- -
-
-
- -
- {% endraw %} - -
- - diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index 6a36599..0000000 --- a/docs/_config.yml +++ /dev/null @@ -1,64 +0,0 @@ -repository: raynardj/forgebox -output: web -topnav_title: forgebox -site_title: forgebox -company_name: xiaochen(ray) zhang -description: Hackings of data science -# Set to false to disable KaTeX math -use_math: true -# Add Google analytics id if you have one and want to use it here -google_analytics: -# See http://nbdev.fast.ai/search for help with adding Search -google_search: - -host: 127.0.0.1 -# the preview server used. Leave as is. -port: 4000 -# the port where the preview is rendered. - -exclude: - - .idea/ - - .gitignore - - vendor - -exclude: [vendor] - -highlighter: rouge -markdown: kramdown -kramdown: - input: GFM - auto_ids: true - hard_wrap: false - syntax_highlighter: rouge - -collections: - tooltips: - output: false - -defaults: - - - scope: - path: "" - type: "pages" - values: - layout: "page" - comments: true - search: true - sidebar: home_sidebar - topnav: topnav - - - scope: - path: "" - type: "tooltips" - values: - layout: "page" - comments: true - search: true - tooltip: true - -sidebars: -- home_sidebar -permalink: pretty - -theme: jekyll-theme-cayman -baseurl: /forgebox/ \ No newline at end of file diff --git a/docs/_data/alerts.yml b/docs/_data/alerts.yml deleted file mode 100644 index 157e162..0000000 --- a/docs/_data/alerts.yml +++ /dev/null @@ -1,15 +0,0 @@ -tip: '
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
show_idtypetitledirectorcastcountrydate_addedrelease_yearratingdurationlisted_indescription
447680145625MovieGod of WarGordon ChanVincent Zhao, Sammo Kam-Bo Hung, Regina Wan, Y...China, Hong KongDecember 16, 20172017NR129 minAction & Adventure, International MoviesA maverick leader and a clever young general t...
432781094074MovieEl Pepe, a Supreme LifeEmir KusturicaJosé Mujica, Emir KusturicaArgentina, Uruguay, SerbiaDecember 27, 20192018TV-1473 minDocumentaries, International MoviesIn this intimate documentary, former Uruguayan...
607880094603TV ShowHighway Thru HellNaNDave Pettitt, Jamie Davis, Adam Gazzola, Kevin...CanadaDecember 3, 20192016TV-PG3 SeasonsReality TVOn the hazardous highways of Canada's interior...
526080044093MovieTeam FoxcatcherJon GreenhalghNaNUnited StatesApril 29, 20162016TV-1491 minDocumentaries, Sports MoviesWith never-before seen home video, this film r...
546481021447MovieThe SilenceJohn R. LeonettiStanley Tucci, Kiernan Shipka, Miranda Otto, K...GermanyApril 10, 20192019TV-1491 minHorror Movies, ThrillersWith the world under attack by deadly creature...
169781043473MovieSGT. Will GardnerMax MartiniMax Martini, Omari Hardwick, Lily Rabe, Elisab...United StatesMay 19, 20192019TV-MA125 minDramasA homeless vet who has PTSD steals a motorcycl...
117880028357MovieLove, RosieChristian DitterLily Collins, Sam Claflin, Christian Cooke, Ja...Germany, United KingdomNovember 20, 20192014R103 minComedies, International Movies, Romantic MoviesOver the years, as they come and go in each ot...
89380190103MovieNaan Sigappu ManithanThiruVishal, Lakshmi Menon, Saranya Ponvannan, Jaya...IndiaOctober 1, 20182014TV-MA147 minAction & Adventure, Dramas, International MoviesAfter his sleeping disorder hinders him from p...
407580156767MovieLa Última FiestaLeandro Mark, Nicolás SilbertNicolás Vázquez, Alan Sabbagh, Benjamín Amadeo...ArgentinaFebruary 1, 20172016TV-MA104 minComedies, International MoviesThree best buddies are thrown into a wild chas...
578380027373TV ShowOh No! It's an Alien InvasionNaNAl Mukadam, Dan Chameroy, Seán Cullen, Stacey ...CanadaMay 31, 20152014TV-Y7-FV2 SeasonsKids' TV, TV Action & Adventure, TV Sci-Fi & F...Nate and his Super Wicked Extreme Emergency Te...
- - - - - - - - - -
-
-

So... what Y?

-
-
-
-
-
- -
-
-
df.listed_in.value_counts()
-
- -
-
-
- -
-
- -
- - - -
-
Documentaries                                                   299
-Stand-Up Comedy                                                 273
-Dramas, International Movies                                    248
-Dramas, Independent Movies, International Movies                186
-Comedies, Dramas, International Movies                          174
-                                                               ... 
-TV Dramas, TV Mysteries, TV Thrillers                             1
-Kids' TV, TV Dramas, Teen TV Shows                                1
-Romantic TV Shows, Spanish-Language TV Shows, TV Comedies         1
-Classic & Cult TV, TV Horror, TV Mysteries                        1
-International TV Shows, Spanish-Language TV Shows, TV Horror      1
-Name: listed_in, Length: 461, dtype: int64
-
- -
- -
-
- -
-
-
- -
-
-
df.rating.value_counts()
-
- -
-
-
- -
-
- -
- - - -
-
TV-MA       2027
-TV-14       1698
-TV-PG        701
-R            508
-PG-13        286
-NR           218
-PG           184
-TV-Y7        169
-TV-G         149
-TV-Y         143
-TV-Y7-FV      95
-G             37
-UR             7
-NC-17          2
-Name: rating, dtype: int64
-
- -
- -
-
- -
-
-
- -
-
-
df["listed_in"] = df.listed_in.str\
-.replace("&",",")\
-.replace(" , ",",")\
-.replace(" ,",",")\
-.replace(", ",",")\
-.replace(" , ",",")
-
- -
-
-
- -
-
-
- -
-
-
genre = list(set(i.strip() for i in (",".join(list(df.listed_in))).split(",")))
-
- -
-
-
- -
-
-
- -
-
-
print(f"Total genre: {len(genre)}\n")
-for g in genre:
-    print(g,end="\t")
-
- -
-
-
- -
-
- -
- -
-
Total genre: 49
-
-Teen TV Shows	Nature TV	Romantic TV Shows	TV Sci-Fi	Action	Faith	Talk Shows	TV Shows	TV Dramas	Thrillers	Sci-Fi	Sports Movies	TV Thrillers	Movies	Cult Movies	Docuseries	TV Comedies	TV Action	Children	Classic Movies	Korean TV Shows	Dramas	TV Horror	Romantic Movies	Spirituality	International TV Shows	Independent Movies	Stand-Up Comedy	Science	Horror Movies	TV Mysteries	Music	Reality TV	Crime TV Shows	Adventure	Classic	Spanish-Language TV Shows	Family Movies	Documentaries	Anime Series	Musicals	Fantasy	Kids' TV	Anime Features	Comedies	British TV Shows	International Movies	LGBTQ Movies	Cult TV	
-
-
- -
-
- -
-
-
- -
-
-
eye = np.eye(len(genre))
-genre_dict = dict((v,eye[k]) for k,v in enumerate(genre))
-
-def to_nhot(text):
-    return np.sum(list(genre_dict[g.strip()] for g in text.split(",")),axis=0).astype(np.int)
-
-df["genre"] = df.listed_in.apply(to_nhot)
-
- -
-
-
- -
-
-
- -
-
-
PROCESSED = "processed.csv"
-
- -
-
-
- -
-
-
- -
-
-
df.to_csv(PROCESSED,index = False)
-
- -
-
-
- -
-
-
-

Process the text

-
-
-
-
- -
-
- -
-
- -
- - -
-

split_df[source]

split_df(df, valid=0.2, ensure_factor=2)

-
-

df: dataframe -valid: valid ratio, default 0.1 -ensure_factor, ensuring the row number to be the multiplication of this factor, default 2 -return train_df, valid_df

- -
- -
- -
-
- -
-
-
- -
-
-
train_df,val_df = split_df(df,valid=0.1)
-print(f"train:{len(train_df)}\tvalid:{len(val_df)}")
-
- -
-
-
- -
-
- -
- -
-
train:5624	valid:608
-
-
-
- -
-
- -
-
-
- -
-
-
from nltk.tokenize import TweetTokenizer
-tkz = TweetTokenizer()
-def tokenize(txt):
-    return tkz.tokenize(txt)
-
- -
-
-
- -
-
-
- -
-
-
tokenize("A man returns home after being released from ")
-
- -
-
-
- -
-
- -
- - - -
-
['A', 'man', 'returns', 'home', 'after', 'being', 'released', 'from']
-
- -
- -
-
- -
-
-
-

Generate vocabulary map from material

-
-
-
-
- -
-
- -
-
- -
- - -
-

class Vocab[source]

Vocab(iterative, tokenize, max_vocab=20000, nproc=10)

-
- -
- -
- -
-
- -
-
-
- -
-
-
vocab = Vocab(df.description,tokenize=tokenize)
-
- -
-
-
- -
-
-
-

Vocabulary build from training

-
-
-
-
-
- -
-
-
vocab.words
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
tokctidx
0four992
1drama993
2brother974
3himself975
4evil956
............
19519Gora119521
19520High-strung119522
19521out-of-the-way119523
0<eos>-10
1<mtk>-11
-

19524 rows × 3 columns

-
-
- -
- -
-
- -
-
- -
-
- -
-
- -
- - -
-

class seqData[source]

seqData(lines, vocab, max_len=-1) :: Dataset

-
-

An abstract class representing a :class:Dataset.

-

All datasets that represent a map from keys to data samples should subclass -it. All subclasses should overwrite :meth:__getitem__, supporting fetching a -data sample for a given key. Subclasses could also optionally overwrite -:meth:__len__, which is expected to return the size of the dataset by many -:class:~torch.utils.data.Sampler implementations and the default options -of :class:~torch.utils.data.DataLoader.

-

.. note:: - :class:~torch.utils.data.DataLoader by default constructs a index - sampler that yields integral indices. To make it work with a map-style - dataset with non-integral indices/keys, a custom sampler must be provided.

- -
- -
- -
-
- -
-
- -
-
- -
- - -
-

class arrData[source]

arrData(*arrs) :: Dataset

-
-

An abstract class representing a :class:Dataset.

-

All datasets that represent a map from keys to data samples should subclass -it. All subclasses should overwrite :meth:__getitem__, supporting fetching a -data sample for a given key. Subclasses could also optionally overwrite -:meth:__len__, which is expected to return the size of the dataset by many -:class:~torch.utils.data.Sampler implementations and the default options -of :class:~torch.utils.data.DataLoader.

-

.. note:: - :class:~torch.utils.data.DataLoader by default constructs a index - sampler that yields integral indices. To make it work with a map-style - dataset with non-integral indices/keys, a custom sampler must be provided.

- -
- -
- -
-
- -
-
-
-

Build vocabulary and train dataset

- -
-
-
-
-
- -
-
-
vocab = Vocab(df.description,tokenize=tokenize)
-
-train_seq = seqData(train_df.description,vocab)
-train_y = arrData(np.stack(train_df.genre.values))
-
-val_seq = seqData(val_df.description,vocab)
-val_y = arrData(np.stack(val_df.genre.values))
-
- -
-
-
- -
-
-
-

Size of train dataset

- -
-
-
-
-
- -
-
-
len(train_seq),len(train_y)
-
- -
-
-
- -
-
- -
- - - -
-
(5624, 5624)
-
- -
- -
-
- -
-
-
- -
-
-
tokenized_line = train_seq[10]
-tokenized_line
-
- -
-
-
- -
-
- -
- - - -
-
array([   0, 4908, 1613, 3527, 2113, 4873,  908, 4819, 8186,  569, 8480,
-       8163, 1476,  579, 4989, 1460, 9109, 1544, 8850, 3102,  908, 3233,
-        941, 5001, 1454, 2152, 3246, 5055, 1454, 8480, 4974, 8019, 8019,
-       8589,  579,    0])
-
- -
- -
-
- -
-
-
-

Reconstruct the sentence from indices

-

<mtk> means the missing tokens, for they are less frequent than we should hav cared

-
- -
-
-
-
-
- -
-
-
train_seq.backward(tokenized_line)
-
- -
-
-
- -
-
- -
- - - -
-
"<eos> Comedian Maria Bamford stars in a series inspired by her own life . It's the sometimes surreal story of a woman who loses – and then finds – her s * * t . <eos>"
-
- -
- -
-
- -
-
-
-

A custom made collate function

    -
  • Collate function will do the following:

    Make rows of dataset output into a batch of tensor

    -
    -
  • -
- -
-
-
-
-
- -
-
-
gen = iter(DataLoader(train_seq,batch_size=16, collate_fn=train_seq.collate))
-next(gen).size()
-
- -
-
-
- -
-
- -
- - - -
-
torch.Size([16, 36])
-
- -
- -
-
- -
-
- -
-
- -
-
- -
- - -
-

class fuse[source]

fuse(*datasets) :: Dataset

-
-

An abstract class representing a :class:Dataset.

-

All datasets that represent a map from keys to data samples should subclass -it. All subclasses should overwrite :meth:__getitem__, supporting fetching a -data sample for a given key. Subclasses could also optionally overwrite -:meth:__len__, which is expected to return the size of the dataset by many -:class:~torch.utils.data.Sampler implementations and the default options -of :class:~torch.utils.data.DataLoader.

-

.. note:: - :class:~torch.utils.data.DataLoader by default constructs a index - sampler that yields integral indices. To make it work with a map-style - dataset with non-integral indices/keys, a custom sampler must be provided.

- -
- -
- -
-
- -
-
-
-

Fusing data set

-
-
-
-
-
- -
-
-
train_ds = fuse(train_seq,train_y)
-val_ds = fuse(val_seq,val_y)
-
- -
-
-
- -
-
-
-

Testing Generator

-
-
-
-
-
- -
-
-
gen = iter(DataLoader(train_ds,batch_size=16, collate_fn=train_ds.collate))
-x,y = next(gen)
-print(x.shape,y.shape)
-
- -
-
-
- -
-
- -
- -
-
torch.Size([16, 36]) torch.Size([16, 49])
-
-
-
- -
-
- -
-
-
-

Model

-
-
-
-
-
- -
-
-
from torch import nn
-import torch
-
- -
-
-
- -
-
-
- -
-
-
class basicNLP(nn.Module):
-    def __init__(self, hs):
-        super().__init__()
-        self.hs = hs
-        self.emb = nn.Embedding(len(vocab),hs)
-        self.rnn = nn.LSTM(input_size = hs,hidden_size = hs,batch_first = True)
-        self.fc = nn.Sequential(*[
-            nn.BatchNorm1d(hs*2),
-            nn.ReLU(),
-            nn.Linear(hs*2,hs*2),
-            nn.BatchNorm1d(hs*2),
-            nn.ReLU(),
-            nn.Linear(hs*2,49),
-        ])
-        
-    def encoder(self,x):
-        x = self.emb(x)
-        o1,(h1,c1) = self.rnn(x)
-        # run sentence backward
-        o2,(h2,c2) = self.rnn(x.flip(dims=[1]))
-        return torch.cat([h1[0],h2[0]],dim=1)
-        
-    def forward(self,x):
-        vec = self.encoder(x)
-        return self.fc(vec)
-
- -
-
-
- -
-
-
- -
-
-
model = basicNLP(100)
-
- -
-
-
- -
-
-
- -
-
-
x[:2,:]
-
- -
-
-
- -
-
- -
- - - -
-
tensor([[    0,  1477,  8844,  2473, 10957, 10958,  4973,   942,  8502,  8945,
-           940,  8844,   923,  2068,   908,  9196,   957,  2153,  8481,  8851,
-          8873,  1454,  2152,  4741,  1460, 10959,   916,  6700,   579,     0,
-             1,     1,     1,     1,     1,     1],
-        [    0,  9024,   765,  4886,  8086,   948,  8491,  4790,  2467,  2112,
-          1460,  8940,  8833,  8781,  5183,  1118,  3231,  8576,  9070, 12932,
-           579,     0,     1,     1,     1,     1,     1,     1,     1,     1,
-             1,     1,     1,     1,     1,     1]])
-
- -
- -
-
- -
-
-
-

What does embedding do?

-
-
-
-
-
- -
-
-
x.shape,model.emb(x).shape
-
- -
-
-
- -
-
- -
- - - -
-
(torch.Size([16, 36]), torch.Size([16, 36, 100]))
-
- -
- -
-
- -
-
-
-

What does LSTM return?

-
-
-
-
-
-

For what is LSTM, read this awesome blog, from which I stole the following visualization from

- -
-
-
-
-
-

In short version

RNN, it's about sharing model weights throughout temporal sequence, as convolusion share weights in spatial point of view -https://colah.github.io/posts/2015-08-Understanding-LSTMs/img/RNN-unrolled.png

-
    -
  • The above green "A" areas are shared linear layer
  • -
  • GRU & LSTM are advanced version of RNN, with gate control
  • -
  • The black arrows above in GRU & LSTM are controlled by gates
  • -
  • Gates, are just linear layer with sigmoid activation $\sigma(x)$, its outputs are between (0,1), hence the name gate, the following illustration is one of the gates in a lstm cell, called input gate -https://colah.github.io/posts/2015-08-Understanding-LSTMs/img/LSTM3-focus-f.png
  • -
  • Other gates control other things like should we forget the early part of then sentence, should we output this .etc
  • -
- -
-
-
-
-
-

In terms of code

-
-
-
-
-
- -
-
-
%time 
-output,(hidden_state, cell_state) = model.rnn(model.emb(x))
-for t in (output,hidden_state, cell_state):
-    print(t.shape)
-
- -
-
-
- -
-
- -
- -
-
CPU times: user 3 µs, sys: 0 ns, total: 3 µs
-Wall time: 7.15 µs
-torch.Size([16, 34, 100])
-torch.Size([1, 16, 100])
-torch.Size([1, 16, 100])
-
-
-
- -
-
- -
-
-
-

Disect the iteration through the sentence

- -
-
-
-
-
- -
-
-
%time
-init_hidden = torch.zeros((1,16,100))
-init_cell = torch.zeros((1,16,100))
-last_h,last_c = init_hidden,init_cell
-outputs = []
-x_vec = model.emb(x)
-for row in range(x.shape[1]):
-    last_o, (last_h,last_c) = model.rnn(x_vec[:,row:row+1,:],(last_h,last_c))
-    outputs.append(last_o)
-
- -
-
-
- -
-
- -
- -
-
CPU times: user 2 µs, sys: 1e+03 ns, total: 3 µs
-Wall time: 6.44 µs
-
-
-
- -
-
- -
-
-
- -
-
-
manual_iteration_result = torch.cat(outputs,dim=1)
-
- -
-
-
- -
-
-
- -
-
-
manual_iteration_result.shape
-
- -
-
-
- -
-
- -
- - - -
-
torch.Size([16, 34, 100])
-
- -
- -
-
- -
-
-
-

The 2 results are the same, of course, I thought manual python iteration is slower,but they are really close by the above test

- -
-
-
-
-
- -
-
-
(manual_iteration_result==output).float().mean()
-
- -
-
-
- -
-
- -
- - - -
-
tensor(1.)
-
- -
- -
-
- -
-
-
-

Training

-
-
-
-
-
- -
-
-
lossf = nn.BCEWithLogitsLoss()
-
- -
-
-
- -
-
-
- -
-
-
from forgebox.ftorch.train import Trainer
-from forgebox.ftorch.callbacks import stat
-from forgebox.ftorch.metrics import metric4_bi
-
- -
-
-
- -
-
-
- -
-
-
model = model.cuda()
-
- -
-
-
- -
-
-
- -
-
-
t = Trainer(train_ds, val_dataset=val_ds,batch_size=16,callbacks=[stat], val_callbacks=[stat] ,shuffle=True,)
-
- -
-
-
- -
-
- -
- -
-
============================================================
-Notice, The Trainer was not initiated with optimizer
-            Use the following syntax to initialize optimizer
-            t.opt["adm1"] = torch.optim.Adam(m1.parameters())
-            t.opt["adg1"] = torch.optim.Adagrad(m2.parameters())
-============================================================
-            
-
-
-
- -
-
- -
-
-
- -
-
-
t.opt["adm1"] = torch.optim.Adam(model.parameters())
-
- -
-
-
- -
-
-
-

Combined collate function

- -
-
-
-
-
- -
-
-
t.train_data.collate_fn = combine_collate(pad_collate,default_collate)
-t.val_data.collate_fn = combine_collate(pad_collate,default_collate)
-
- -
-
-
- -
-
-
- -
-
-
@t.step_train
-def train_step(self):
-    self.opt.zero_all()
-    x,y = self.data
-    y_= model(x)
-    loss = lossf(y_,y.float())
-    loss.backward()
-    self.opt.step_all()
-    acc,rec,prec,f1 = metric4_bi(torch.sigmoid(y_),y)
-    return dict((k,v.item()) for k,v in zip(["loss","acc","rec","prec","f1"],(loss,acc,rec,prec,f1)))
-                
-@t.step_val
-def val_step(self):
-    x,y = self.data
-    y_= model(x)
-    loss = lossf(y_,y.float())
-    acc,rec,prec,f1 = metric4_bi(torch.sigmoid(y_),y)
-    return dict((k,v.item()) for k,v in zip(["loss","acc","rec","prec","f1"],(loss,acc,rec,prec,f1)))
-
- -
-
-
- -
-
-
- -
-
-
t.train(10)
-
- -
-
-
- -
-
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1915030.9436050.0183550.252630.0663620.0174.50.012922
min0.1335930.4987240.0000000.000000.0392160.00.00.000000
max0.7176840.9630100.4523811.000000.2105260.0349.04.522615
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1661950.9498200.0140630.4552850.0529170.020.00.016862
min0.1336250.9336730.0000000.0000000.0425530.00.00.000000
max0.2083610.9604590.0625001.0000000.1142860.040.00.691359
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1609530.9497780.0403620.5036840.0968321.0174.50.013533
min0.1137500.9362240.0000000.0000000.0384621.00.00.000000
max0.2048530.9668370.2285711.0000000.3636361.0349.04.736667
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1596490.9497880.0567230.4728220.1137871.020.00.013886
min0.1262140.9413260.0000000.0000000.0454551.00.00.000000
max0.1838200.9591840.1621621.0000000.2727271.040.00.569323
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1502870.9510050.0944980.6192610.16442.0174.50.013062
min0.1074970.9362240.0000000.0000000.04002.00.00.000000
max0.2119890.9668370.2564101.0000000.40002.0349.04.571776
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1582330.9501000.0808530.4990420.1519392.020.00.013032
min0.1003520.9387750.0000000.0000000.0416672.00.00.000000
max0.1995640.9630100.2000001.0000000.3333332.040.00.534303
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1390500.9528260.1555670.6474840.2470373.0174.50.013327
min0.1024040.9362240.0000000.0000000.0384623.00.00.000000
max0.1893700.9706630.3823531.0000000.5106383.0349.04.664611
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1598430.9496330.1051940.4602750.1730603.020.00.012334
min0.1208510.9375000.0000000.0000000.0408163.00.00.000000
max0.2086860.9642860.2812500.9090910.3921573.040.00.505692
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1256110.9558640.2359540.6935940.3472174.0174.50.012675
min0.0781760.9387750.0652170.3333330.1132084.00.00.000000
max0.1867810.9770410.5161291.0000000.6400004.0349.04.436386
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1650550.9477040.1372150.4537380.2065934.020.00.012974
min0.1030900.9323980.0434780.1428570.0701754.00.00.000000
max0.2302520.9591840.2432431.0000000.3600004.040.00.531945
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1106110.9597100.3334780.722260.4509375.0174.50.013399
min0.0729560.9387750.1000000.400000.1600005.00.00.000000
max0.1828410.9770410.6250001.000000.6779665.0349.04.689789
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1758970.9464290.1524440.3911540.2216505.020.00.012744
min0.1218430.9349490.0000000.0000000.0392165.00.00.000000
max0.2248490.9604590.3428570.7500000.4210535.040.00.522507
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.0963000.9639710.4302030.7565480.5434976.0174.50.012643
min0.0604330.9413260.1707320.4736840.2641516.00.00.000000
max0.1810050.9808670.7272731.0000000.7804886.0349.04.425211
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.1855050.9465840.1858380.4306420.2561446.020.00.012818
min0.1169730.9272960.0540540.1250000.0754726.00.00.000000
max0.2595560.9642860.3939390.6923080.4864866.040.00.525531
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.0830810.9677270.5079440.7805870.6111337.0174.50.014348
min0.0525580.9426020.2380950.4848480.3278697.00.00.000000
max0.1404120.9846940.7777781.0000000.8235297.0349.05.021668
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.2045990.9451530.1965500.4180750.2638337.020.00.012317
min0.1322900.9247450.0212770.0714290.0327877.00.00.000000
max0.3910810.9642860.3333331.0000000.4400007.040.00.504995
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.0723080.9719040.5822420.8115310.6743358.0174.50.013954
min0.0444030.9515310.3428570.5454550.4210538.00.00.000000
max0.1131980.9897960.8750001.0000000.8974368.0349.04.884068
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.2194910.9416690.1858540.3450280.2442438.020.00.015648
min0.1380230.9272960.0000000.0000000.0833338.00.00.000000
max0.3261870.9591840.3414630.6000000.4137938.040.00.641576
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.0621070.9758990.6560510.8350320.7311279.0174.50.013415
min0.0314620.9579080.3902440.6296300.5000009.00.00.000000
max0.1034140.9923470.9333331.0000000.9142869.0349.04.695169
-
-
- -
- -
- -
-
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lossaccrecprecf1epochitertimestamp
mean0.2329480.9424150.1912210.3429910.2494189.020.00.014030
min0.1394470.9260200.0000000.0000000.0769239.00.00.000000
max0.3202010.9693880.4117650.6190480.4642869.040.00.575232
-
-
- -
- -
-
- -
-
-
-

Search similar

-
-
-
-
-
- -
-
-
model = model.eval()
-dl = DataLoader(train_seq, batch_size=32, collate_fn=pad_collate)
-
- -
-
-
- -
-
-
- -
-
-
text_gen = iter(dl)
-result = []
-for i in range(len(dl)):
-    x=next(text_gen)
-    x = x.cuda()
-    x_vec = model.encoder(x)
-    result.append(x_vec.cpu())
-
- -
-
-
- -
-
-
-

A vector representing each of the sentence

- -
-
-
-
-
- -
-
-
result_vec = torch.cat(result,dim=0).detach().numpy()
-result_vec.shape
-
- -
-
-
- -
-
- -
- - - -
-
(5590, 200)
-
- -
- -
-
- -
-
-
- -
-
-
def to_idx(line):
-    words = train_seq.vocab.tokenize(line)
-    words = ["<eos>",]+words+["<eos>"]
-    return train_seq.to_i(np.array(words))[None,:]
-
- -
-
-
- -
-
-
- -
-
-
to_idx("this"), to_idx("to be or not to be")
-
- -
-
-
- -
-
- -
- - - -
-
(array([[  0, 913,   0]]),
- array([[   0, 2153, 5056, 1442, 1438, 2153, 5056,    0]]))
-
- -
- -
-
- -
-
-
- -
-
-
def to_vec(line):
-    vec = torch.LongTensor(to_idx(line)).cuda()
-    return model.encoder(vec).cpu().detach().numpy()
-
- -
-
-
- -
-
-
- -
-
-
to_vec("this"), to_vec("to be or not to be")
-
- -
-
-
- -
-
- -
- - - -
-
(array([[-0.2864027 , -0.1188629 , -0.02617935, -0.24850701, -0.20578709,
-          0.06889898,  0.05878495, -0.22658055,  0.15024377, -0.31303164,
-          0.4958601 , -0.00204021,  0.17621423, -0.2538225 , -0.3451157 ,
-         -0.23131247, -0.06265341, -0.17155428, -0.00899762, -0.2577241 ,
-         -0.02896317, -0.4555603 ,  0.6856887 , -0.70418745,  0.11082602,
-         -0.23981036, -0.21201135, -0.43933266, -0.40148616, -0.48364577,
-          0.42605698,  0.41181046, -0.14798354,  0.05320957, -0.4300459 ,
-         -0.06580015,  0.01534137,  0.02928652, -0.53414524, -0.02051809,
-         -0.47986796, -0.12036817, -0.00229292,  0.2772647 ,  0.1102341 ,
-         -0.40527657, -0.11229473, -0.42787483,  0.40304342,  0.3992268 ,
-          0.1696693 , -0.6523132 , -0.3679182 ,  0.0087082 , -0.01391423,
-         -0.21790238, -0.3263417 , -0.29073295,  0.45376575, -0.02547877,
-         -0.08805989, -0.04059793,  0.32122698, -0.10253229,  0.29216015,
-         -0.29081804,  0.7000031 , -0.07116397, -0.03899158,  0.00963022,
-         -0.00503215, -0.18202703, -0.06382827,  0.04819749, -0.39615613,
-         -0.06416079,  0.11534453,  0.05590353,  0.18084338,  0.12755607,
-         -0.40813434, -0.08283492, -0.48865405, -0.0570746 , -0.20188878,
-         -0.49008507, -0.27526015, -0.3434001 , -0.24542893,  0.01706186,
-          0.3014823 , -0.00861376,  0.43119976,  0.11287364,  0.10990695,
-         -0.05565942,  0.3471237 ,  0.39106023,  0.12372674, -0.1318522 ,
-         -0.2864027 , -0.1188629 , -0.02617935, -0.24850701, -0.20578709,
-          0.06889898,  0.05878495, -0.22658055,  0.15024377, -0.31303164,
-          0.4958601 , -0.00204021,  0.17621423, -0.2538225 , -0.3451157 ,
-         -0.23131247, -0.06265341, -0.17155428, -0.00899762, -0.2577241 ,
-         -0.02896317, -0.4555603 ,  0.6856887 , -0.70418745,  0.11082602,
-         -0.23981036, -0.21201135, -0.43933266, -0.40148616, -0.48364577,
-          0.42605698,  0.41181046, -0.14798354,  0.05320957, -0.4300459 ,
-         -0.06580015,  0.01534137,  0.02928652, -0.53414524, -0.02051809,
-         -0.47986796, -0.12036817, -0.00229292,  0.2772647 ,  0.1102341 ,
-         -0.40527657, -0.11229473, -0.42787483,  0.40304342,  0.3992268 ,
-          0.1696693 , -0.6523132 , -0.3679182 ,  0.0087082 , -0.01391423,
-         -0.21790238, -0.3263417 , -0.29073295,  0.45376575, -0.02547877,
-         -0.08805989, -0.04059793,  0.32122698, -0.10253229,  0.29216015,
-         -0.29081804,  0.7000031 , -0.07116397, -0.03899158,  0.00963022,
-         -0.00503215, -0.18202703, -0.06382827,  0.04819749, -0.39615613,
-         -0.06416079,  0.11534453,  0.05590353,  0.18084338,  0.12755607,
-         -0.40813434, -0.08283492, -0.48865405, -0.0570746 , -0.20188878,
-         -0.49008507, -0.27526015, -0.3434001 , -0.24542893,  0.01706186,
-          0.3014823 , -0.00861376,  0.43119976,  0.11287364,  0.10990695,
-         -0.05565942,  0.3471237 ,  0.39106023,  0.12372674, -0.1318522 ]],
-       dtype=float32),
- array([[-4.67454530e-02, -9.31215361e-02,  1.03428781e-01,
-         -7.04722330e-02, -1.75118193e-01,  2.06147537e-01,
-         -1.80195719e-01, -2.96070606e-01, -6.63760230e-02,
-         -1.17778860e-01,  4.16386664e-01, -2.82360259e-02,
-         -9.79896635e-02, -1.64554998e-01, -4.22353059e-01,
-         -2.57056504e-01,  9.54333842e-02, -4.04358506e-01,
-         -2.89067421e-02,  2.24286512e-01, -2.91498333e-01,
-         -5.15985727e-01,  6.25436842e-01, -3.82335573e-01,
-          9.66877778e-05, -5.79554796e-01,  2.49115989e-01,
-         -1.89282358e-01, -5.12709558e-01, -3.26256692e-01,
-         -4.69405144e-01, -7.64686316e-02,  1.47889346e-01,
-          4.15703245e-02, -2.66019195e-01, -2.08178125e-02,
-          2.30910387e-02,  4.07335609e-01, -3.15426886e-01,
-         -2.41327912e-01, -4.37703043e-01,  1.69361576e-01,
-         -5.28552115e-01,  3.17790836e-01, -2.26195082e-01,
-          1.98947728e-01, -5.99721745e-02, -1.17049702e-01,
-          3.48403037e-01,  1.16154104e-01, -9.79769006e-02,
-         -5.31215489e-01, -3.45111728e-01, -1.51543558e-01,
-         -4.74260300e-02, -3.10880184e-01, -2.34046459e-01,
-         -4.89330530e-01,  1.92080900e-01,  8.46387047e-05,
-          5.20091116e-01,  1.19925300e-02, -2.24701278e-02,
-          3.68952841e-01,  3.63212615e-01, -1.76386997e-01,
-          8.03452671e-01, -1.92376554e-01,  2.48082243e-02,
-          4.32565331e-01, -3.37531790e-02, -4.21101004e-02,
-         -2.10536309e-02,  1.79137215e-02, -5.51163614e-01,
-          1.79473273e-02, -2.56144851e-01,  1.43536568e-01,
-          1.14509970e-01, -4.08435524e-01, -6.10258477e-03,
-         -1.82999484e-02, -3.36512983e-01, -4.28514257e-02,
-         -5.26481271e-01, -4.67332840e-01, -5.00806391e-01,
-         -1.97101533e-01, -3.14959913e-01,  2.88293674e-03,
-         -7.90096354e-03, -1.98622406e-01,  3.48969668e-01,
-         -2.70279735e-01, -1.35412514e-01, -1.51752485e-02,
-         -6.74099028e-02, -9.12430584e-02,  6.52649999e-02,
-         -4.96096015e-02, -8.09527710e-02, -1.94839135e-01,
-          7.93975685e-03,  2.51075149e-01, -1.21566914e-01,
-          1.87434196e-01, -4.09827203e-01, -1.85767949e-01,
-         -4.50579636e-02, -8.25710967e-03,  4.34691131e-01,
-         -1.74075253e-02, -2.26057798e-01, -9.93655398e-02,
-         -4.55289811e-01, -1.77727148e-01,  1.51167855e-01,
-         -3.92441899e-01, -3.76366675e-02,  1.91804245e-01,
-         -2.46650815e-01, -2.66600817e-01,  5.98052680e-01,
-         -5.53917885e-01, -5.27672432e-02, -4.28468704e-01,
-          3.21030438e-01, -5.24240211e-02, -5.80894887e-01,
-         -2.62316704e-01, -5.54102123e-01, -2.63558865e-01,
-          7.92699903e-02,  3.08560506e-02, -6.34330451e-01,
-         -2.22378112e-02,  1.90087445e-02,  3.06508392e-01,
-         -4.17445600e-01, -1.65813014e-01, -3.87870014e-01,
-          2.00837955e-01, -5.82205415e-01,  2.10029915e-01,
-         -1.73551142e-01,  2.62706548e-01, -4.51332517e-02,
-         -2.98126251e-01,  1.22165889e-01,  2.69887537e-01,
-         -9.97079089e-02, -4.44641918e-01, -1.94629923e-01,
-         -9.44814011e-02, -5.58075830e-02, -3.08131754e-01,
-         -1.35656327e-01, -4.49017793e-01,  1.57232210e-01,
-          6.85075764e-03,  1.95502162e-01, -3.58620263e-03,
-         -7.33885169e-02,  2.54277617e-01,  3.10389578e-01,
-         -2.30608821e-01,  7.85782695e-01, -1.99842900e-01,
-          2.65866872e-02,  4.02122647e-01, -4.90787327e-02,
-          2.89043874e-01,  7.39292949e-02,  2.30548643e-02,
-         -5.23956776e-01,  8.47117510e-03, -2.22430736e-01,
-          2.78976131e-02,  1.98936775e-01, -3.27527881e-01,
-         -3.42491508e-01,  9.65497643e-03, -3.23785730e-02,
-         -6.30644411e-02, -4.23567891e-01, -4.62936759e-01,
-         -5.00409305e-01, -2.56481886e-01, -2.42299706e-01,
-          6.78150402e-03, -1.47003448e-03, -8.91473442e-02,
-          3.01649749e-01, -2.08600447e-01, -2.30947211e-01,
-          1.51244365e-02,  9.57912132e-02, -7.86154643e-02,
-          9.30957273e-02, -1.24067500e-01]], dtype=float32))
-
- -
- -
-
- -
-
-
- -
-
-
def l2norm(x):
-    """
-    L2 Norm
-    """
-    return np.linalg.norm(x,2,1).reshape(-1,1)
-
- -
-
-
- -
-
-
- -
-
-
pd.set_option("max_colwidth",150)
-
-def search(line):
-    vec = to_vec(line)
-    sim = ((vec* result_vec)/l2norm(result_vec)).sum(-1)
-    return pd.DataFrame({"text":train_seq.lines,"sim":sim})\
-        .sort_values(by="sim",ascending=False)
-
- -
-
-
- -
-
-
- -
-
-
search("Experience our planet's natural beauty").head(10)
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
textsim
4699The year is 2041 and a dispute between a man and his wife has set the human race back. In this battle of the sexes, the primitive life isn't so si...2.796010
1184Ya-nuo's been raised as a boy. Now at age 25, she's caught the eye of a triad leader's sister. But what happens when she reveals her true gender?2.747936
47Scouted by a famous Spanish club, Valt Aoi heads to Spain. With their sights on the World League, he and his teammates face the European League fi...2.684218
1116Led by seventh-grader C.J., three students who have been warned about the dangers of high school decide to make the best of their middle-school ye...2.633265
5380Love is in the air as Zoe and friends go on a quest to find a fabled Maid's Stone. But when rivalry blinds them to danger, it's Raven to the rescue!2.550404
4741The whole huggable gang is back, bringing tales of caring and sharing to a new generation. And now the Care Bear Cousins are here to join the fun!2.546750
4609Captain Atomic – once a superhero, now a sock puppet – can only activate his powers with the help of Joey, his new partner and biggest fan.2.545124
3574Sometimes being shady is the only way to survive, a fact these sneaky animal "hustlers" – including orcas, owls and otters – use to their advantage.2.517003
2686Comedian Maria Bamford stars in a series inspired by her own life. It's the sometimes surreal story of a woman who loses – and then finds – her s**t.2.510907
1039Thom tells her grandson about his grandfather, a sailor who left 61 years ago to seek his fortune, and asks him to find out what happened to her s...2.499740
-
-
- -
- -
-
- -
-
-
- -
-
-
search("love story,marriage, girl").head(10)
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
textsim
1588To her Indian parents' dismay, London-born Jasmeet "Jazz" Malhotra longs for everything Western, including her British boyfriend. On a family trip...2.468083
4285Quick to throw punches in the name of justice, a young man must find a calmer way to win over the pacifist father of the girl he wishes to marry.2.414226
504When Parisian Elsa gets hung up on her ex, her best friends secretly hire a male escort to help her move on. But their plan works a little too well.2.391777
2595Motu and Patlu want to help a circus lion get back to the jungle. On the way, the three become caught up in an exciting adventure in the forest.2.369020
652Hoping to find a magical root, a monster has captured farmers in the land of Vyom. It’s up to Bheem and the gang to foil his plan and save the kin...2.363151
2042Tired of her passionless marriage, Marianne wants a separation from her husband, Gustav, who, in response, decides to make a big change of his own.2.361425
1668In 1962 Brooklyn, a Puerto Rican teen who joins a gang is seduced by violence and heroin. But can his mother's love and faith in God save him?2.344456
2478Maya finally hooks up with her online dream girl, only to discover she’s deeply involved with an older sugar daddy – a man Maya knows all too well.2.337689
1324After an argument with her dad, a young woman from a family of macho truck drivers is kicked out of the home and must make her own success as a tr...2.334984
177Little Singham is in London to meet the queen, but when the famed Kohinoor Diamond gets stolen, the kid cop goes on a wild, citywide hunt for the ...2.310921
-
-
- -
- -
-
- -
-
-
-

Well, usually it should be more accurate if we have more data

- -
-
-
- {% endraw %} - - - - - diff --git a/docs/category.html b/docs/category.html deleted file mode 100644 index 292135e..0000000 --- a/docs/category.html +++ /dev/null @@ -1,968 +0,0 @@ ---- - -title: Categorical Transformation for DL - - -keywords: fastai -sidebar: home_sidebar - -summary: "a list of things to categoryical transformation" -description: "a list of things to categoryical transformation" -nb_path: "nbs/53_category.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - -
-
-

Imports

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

class C2I[source]

C2I(arr:Iterable[T_co], pad_mst:bool=False)

-
-

Category to indices

-

c2i = C2I( - ["class 1", "class 2", ..., "class n"], - pad_mst=True, - ) -c2i[["class 2", "class 5"]] -[0] array([2,3])

-
-
-
-

If the indices you put in the slicing is a np.ndarray - a verctorized function will be used

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

class Category[source]

Category(arr:Iterable[T_co], pad_mst:bool=False)

-
-

Manage categorical translations -c = Category( - ["class 1", "class 2", ..., "class n"], - pad_mst=True,)

-

c.c2i[["class 3","class 6"]] -c.i2c[[3, 2, 1]]

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

class TreeCategory[source]

TreeCategory(parent_map:Dict[str, str], pad_mst:bool=False) :: Category

-
-

Manage categorical translations -c = Category( - ["class 1", "class 2", ..., "class n"], - pad_mst=True,)

-

c.c2i[["class 3","class 6"]] -c.i2c[[3, 2, 1]]

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Indexing forward and backward

-
-
-
- {% raw %} - -
-
- -
-
-
cates = Category(list(map(lambda x:f"Cate_{x+1}",range(50))))
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
cates
-
- -
-
-
- -
-
- -
- - - -
-
Category Manager with 50
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
cates.i2c[:5]
-
- -
-
-
- -
-
- -
- - - -
-
array(['Cate_1', 'Cate_2', 'Cate_3', 'Cate_4', 'Cate_5'], dtype='<U7')
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
test_c = np.random.randint(1,50,1000)
-
- -
-
-
- -
- {% endraw %} - -
-
-

Indices to categories

-
-
-
- {% raw %} - -
-
- -
-
-
labels = cates.i2c[test_c]
-labels[:20]
-
- -
-
-
- -
-
- -
- - - -
-
array(['Cate_3', 'Cate_21', 'Cate_41', 'Cate_29', 'Cate_3', 'Cate_5',
-       'Cate_5', 'Cate_40', 'Cate_3', 'Cate_24', 'Cate_10', 'Cate_19',
-       'Cate_37', 'Cate_45', 'Cate_35', 'Cate_36', 'Cate_28', 'Cate_8',
-       'Cate_13', 'Cate_23'], dtype='<U7')
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Category to indices

-
-
-
- {% raw %} - -
-
- -
-
-
cates.c2i[labels[:20]]
-
- -
-
-
- -
-
- -
- - - -
-
array([ 2, 20, 40, 28,  2,  4,  4, 39,  2, 23,  9, 18, 36, 44, 34, 35, 27,
-        7, 12, 22])
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Using vectorized function

- -
-
-
- {% raw %} - -
-
- -
-
-
%%time
-for i in range(200):
-    indices_generated = cates.c2i[labels]
-
- -
-
-
- -
-
- -
- -
-
CPU times: user 59.8 ms, sys: 2.67 ms, total: 62.4 ms
-Wall time: 62.4 ms
-
-
-
- -
-
- -
- {% endraw %} - -
-
-

Using the original python function

- -
-
-
- {% raw %} - -
-
- -
-
-
%%time
-for i in range(200):
-    indices_generated2 = list(cates.c2i.get_int(l) for l in labels)
-
- -
-
-
- -
-
- -
- -
-
CPU times: user 102 ms, sys: 2.31 ms, total: 104 ms
-Wall time: 104 ms
-
-
-
- -
-
- -
- {% endraw %} - -
-
-

Transform forward and backward and check fidelity

- -
-
-
- {% raw %} - -
-
- -
-
-
(cates.c2i[labels]==test_c).mean()
-
- -
-
-
- -
-
- -
- - - -
-
1.0
-
- -
- -
-
- -
- {% endraw %} - -
-
-

With missing tokens

-
-
-
-
-
-

We can set pad_mst to True to manage missing token

- -
-
-
- {% raw %} - -
-
- -
-
-
nt = Category("ATCG", pad_mst=True)
-
- -
-
-
- -
- {% endraw %} - -
-
-

Categories to indices

-
-
-
- {% raw %} - -
-
- -
-
-
nt.c2i[list("AAACCTTATTGCAGCOAAT")]
-
- -
-
-
- -
-
- -
- - - -
-
array([1, 1, 1, 3, 3, 2, 2, 1, 2, 2, 4, 3, 1, 4, 3, 0, 1, 1, 2])
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Indices to categories

-
-
-
- {% raw %} - -
-
- -
-
-
nt.i2c[[1, 1, 1, 3, 3, 2, 2, 2, 2, 4, 3, 1, 4, 3, 0, 1, 1, 2]]
-
- -
-
-
- -
-
- -
- - - -
-
array(['A', 'A', 'A', 'C', 'C', 'T', 'T', 'T', 'T', 'G', 'C', 'A', 'G',
-       'C', '[MST]', 'A', 'A', 'T'], dtype='<U5')
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Data save and load

-
-
-
-
-
-

Save categories

-
-
-
- {% raw %} - -
-
- -
-
-
nt.save("atcg.json")
-
- -
-
-
- -
- {% endraw %} - -
-
-

Load categories

-
-
-
- {% raw %} - -
-
- -
-
-
cm = Category.load("atcg.json")
-cm
-
- -
-
-
- -
-
- -
- - - -
-
Category Manager with 5
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Tree data

-
-
-
-
-
-

Sometime the target should be treated like a tree structure multi-hotting, not one-hot encoding, the benifit of such operation is explained in this colab notebook

- -
-
-
- {% raw %} - -
-
- -
-
-
import requests
-
-tree_str = requests.get("http://oncotree.mskcc.org/api/tumorTypes/tree?&version=oncotree_latest_stable").text
-tree = json.loads(tree_str)
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
parent_map = dict()
-def get_pairs(node):
-    if "name" in node:
-        parent_map.update({node.get("code"):node.get("parent")})
-    if "children" in node:
-        for c,child in node["children"].items():
-            get_pairs(child)
-
-get_pairs(tree['TISSUE'])
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
tree_category = TreeCategory(parent_map)
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
tree_category
-
- -
-
-
- -
-
- -
- - - -
-
Tree Category(869):
-	self.tree_hot("name")	self.ancestor_map	self.depth_map_array
-
- -
- -
-
- -
- {% endraw %} - -
-
-

You can transform the category data into the following multihot hierachical encoding vector.

-

The rest is good old BCELoss

- -
-
-
- {% raw %} - -
-
- -
-
-
tree_category.tree_hot("NCCRCC")
-
- -
-
-
- -
-
- -
- - - -
-
array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
tree_category.depth_map_array
-
- -
-
-
- -
-
- -
- - - -
-
array([1, 2, 3, 4, 4, 4, 3, 4, 4, 5, 5, 4, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4,
-       4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 2, 3,
-       4, 5, 5, 5, 5, 5, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 4, 5, 6,
-       6, 7, 7, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
-       7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 6, 6, 6, 6, 7, 6,
-       7, 7, 6, 6, 7, 7, 7, 6, 7, 7, 5, 6, 6, 6, 6, 7, 7, 7, 6, 6, 6, 6,
-       6, 6, 6, 6, 6, 6, 6, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 5,
-       6, 6, 6, 6, 4, 5, 5, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3,
-       3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-       3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 4, 3, 4, 3, 4, 4, 4, 4, 4, 2, 3,
-       3, 3, 4, 4, 3, 3, 3, 3, 2, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 3, 3, 3,
-       4, 4, 4, 4, 4, 3, 2, 3, 4, 4, 4, 3, 3, 4, 4, 4, 3, 2, 3, 3, 4, 3,
-       3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 4, 3, 3, 4, 5, 5, 5, 4, 3,
-       3, 4, 5, 5, 5, 4, 5, 5, 5, 2, 3, 3, 3, 4, 3, 4, 4, 4, 4, 4, 4, 3,
-       4, 5, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-       3, 2, 3, 4, 4, 3, 3, 4, 4, 2, 3, 4, 4, 4, 2, 3, 4, 4, 3, 2, 3, 3,
-       3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 4, 4, 4, 4, 3, 3, 2,
-       3, 3, 3, 4, 4, 5, 5, 4, 3, 2, 3, 4, 4, 4, 4, 3, 3, 3, 4, 3, 3, 3,
-       3, 4, 4, 4, 4, 3, 3, 3, 4, 4, 4, 4, 4, 2, 3, 3, 4, 4, 3, 4, 4, 4,
-       4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 2, 3, 3, 3, 3, 3, 3,
-       3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3,
-       2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 3, 3, 4, 2, 3, 4, 4,
-       4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4,
-       5, 5, 5, 4, 4, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 3, 4, 4, 4, 4, 4, 4,
-       4, 4, 3, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4,
-       4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4,
-       4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 2, 3, 3, 3, 2, 3, 3, 3, 3,
-       3, 2, 3, 4, 4, 4, 4, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 4, 4, 5, 5, 5,
-       5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 3, 4, 4, 4, 2, 3, 4, 4, 5, 5, 5, 5,
-       5, 4, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
-       4, 5, 5, 5, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
-       3, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2,
-       3, 3, 2, 3, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 5, 6, 6,
-       5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 5, 5, 5, 5, 5,
-       5, 5, 5, 5, 4, 4, 5, 5, 5, 5, 5, 4, 5, 5, 5, 6, 6, 6, 5, 5, 4, 5,
-       5, 6, 5, 6, 5, 6, 6, 5, 5, 5, 6, 4, 4, 5, 5, 5, 5, 4, 5, 6, 6, 5,
-       6, 6, 5, 5, 5, 5, 5, 4, 5, 5, 6, 6, 6, 6, 6, 5, 3, 2, 3, 3, 4, 4,
-       4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-       5, 5, 5, 4, 5, 3, 3, 3, 3, 2, 3, 4, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4,
-       5, 5, 4, 3, 3, 3, 4, 4, 4, 3, 3])
-
- -
- -
-
- -
- {% endraw %} - -
-
-

With the above array, you can achieve many tasks.

-

eg. you can calc accuracy, loss, f1 for each level

-
crit = nn.BCEWithLogitLoss()
-def accuracy(y,y_): return (y==(y_>.5)).float().mean()
-loss = crit(y,y_)
-acc = accuracy(y,y_)
-
-level_map = torch.LongTensor(tree_category.depth_map_array).cuda()
-
-# calc metrics for level2, level3, level4
-loss_l = dict()
-acc_l = dict()
-for level in [2,3,4]:
-    y_level = y[level_map==level]
-    y_hat_level = y_[level_map==level]
-    loss_l[level] = crit(y_level, y_hat_level)
-    acc_l[level] = accuracy(y_level, y_hat_level)
-
-

Or assign different weights to different level of loss, etc.

-

Visualize level for first 100 categories

- -
-
-
- {% raw %} - -
-
- -
-
-
from matplotlib import pyplot as plt
-plt.figure(figsize=(20,10))
-plt.imshow(
-    np.stack(list(tree_category.depth_map_array==i
-                  for i in range(1,tree_category.depth_map_array.max()+1)))[:,:100])
-
- -
-
-
- -
-
- -
- - - -
-
<matplotlib.image.AxesImage at 0x1c375535d0>
-
- -
- -
- - - -
- -
- -
- -
-
- -
- {% endraw %} - -
- - diff --git a/docs/config.html b/docs/config.html deleted file mode 100644 index 9cebb7f..0000000 --- a/docs/config.html +++ /dev/null @@ -1,460 +0,0 @@ ---- - -title: Config - -keywords: fastai -sidebar: home_sidebar - - - ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

class Config[source]

Config() :: dict

-
-

dict() -> new empty dictionary -dict(mapping) -> new dictionary initialized from a mapping object's - (key, value) pairs -dict(iterable) -> new dictionary initialized as if via: - d = {} - for k, v in iterable: - d[k] = v -dict(**kwargs) -> new dictionary initialized with the name=value pairs - in the keyword argument list. For example: dict(one=1, two=2)

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

first[source]

first(d, key)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

getall[source]

getall(d, key)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
dict.items
-
- -
-
-
- -
-
- -
- - - -
-
<method 'items' of 'dict' objects>
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
config = Config(a = 1,z=3,b=2,c=[dict(d=5,e=6,z=5),dict(g=7,h=dict(i=8,z=6))])
-config.pretty_print()
-
- -
-
-
- -
-
- -
- -
-
{
-    "a": 1,
-    "z": 3,
-    "b": 2,
-    "c": [
-        {
-            "d": 5,
-            "e": 6,
-            "z": 5
-        },
-        {
-            "g": 7,
-            "h": {
-                "i": 8,
-                "z": 6
-            }
-        }
-    ]
-}
-
-
-
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
config.first("z")
-
- -
-
-
- -
-
- -
- - - -
-
3
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
config.getall("z")
-
- -
-
-
- -
-
- -
- - - -
-
[3, 5, 6]
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Pretty print config

-
-
-
- {% raw %} - -
-
- -
-
-
Config(a=1,b=2).pretty_print()
-
- -
-
-
- -
-
- -
- -
-
{
-    "a": 1,
-    "b": 2
-}
-
-
-
- -
-
- -
- {% endraw %} - -
-
-

Multiple ways of setting config

-
-
-
- {% raw %} - -
-
- -
-
-
config = Config(a=1,b=2)(c=5)(d=6)
-config.e=12
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
config
-
- -
-
-
- -
-
- -
- - - -
-
{'a': 1, 'b': 2, 'c': 5, 'd': 6, 'e': 12}
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Save and load json

-
-
-
- {% raw %} - -
-
- -
-
-
config.save("test.json")
-!cat test.json
-
- -
-
-
- -
-
- -
- -
-
{"a": 1, "b": 2, "c": 5, "d": 6, "e": 12}
-
-
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
Config.load("test.json")
-
- -
-
-
- -
-
- -
- - - -
-
{'a': 1, 'b': 2, 'c': 5, 'd': 6, 'e': 12}
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
!rm test.json
-
- -
-
-
- -
- {% endraw %} - -
- - diff --git a/docs/cosine_search.html b/docs/cosine_search.html deleted file mode 100644 index 17b183c..0000000 --- a/docs/cosine_search.html +++ /dev/null @@ -1,268 +0,0 @@ ---- - -title: Cosine - - -keywords: fastai -sidebar: home_sidebar - - - -nb_path: "nbs/55_cosine_search.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Cosine Similarity

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

class CosineSearch[source]

CosineSearch(base)

-
-

Build a index search on cosine distance

-

cos = CosineSearch(base_array) -idx_order = cos(vec)

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

class CosineSearchWithCategory[source]

CosineSearchWithCategory(base:ndarray, category:ndarray) :: CosineSearch

-
-

Combine with the category manager -The class can return a dataframe with category information

-

search_dataframe

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
- -
-
-
- {% raw %} - -
-
- -
-
-
base = np.random.rand(50000,100)-.2
-vec = base[200]
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
cosine = CosineSearch(base)
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
cosine(vec)
-
- -
-
-
- -
-
- -
- - - -
-
array([  200, 42154,  2439, ..., 45360, 13398,  9083])
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
cosine.search(vec, return_similarity=True)
-
- -
-
-
- -
-
- -
- - - -
-
(array([  200, 42154,  2439, ..., 45360, 13398,  9083]),
- array([0.22396417, 0.16316632, 0.16174796, ..., 0.06436053, 0.06367614,
-        0.0608117 ]))
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
 
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
%%time
-for i in range(100):
-    cosine(vec)
-
- -
-
-
- -
-
- -
- -
-
CPU times: user 1.21 s, sys: 147 ms, total: 1.36 s
-Wall time: 1.37 s
-
-
-
- -
-
- -
- {% endraw %} - -
- - diff --git a/docs/create_different.html b/docs/create_different.html deleted file mode 100644 index 3617f1b..0000000 --- a/docs/create_different.html +++ /dev/null @@ -1,29 +0,0 @@ ---- - -title: create different file - -keywords: fastai -sidebar: home_sidebar - -summary: "different file" ---- - - -
- {% raw %} - -
- -
- {% endraw %} -
- - diff --git a/docs/cross_entropy_weighter.html b/docs/cross_entropy_weighter.html deleted file mode 100644 index 2756f81..0000000 --- a/docs/cross_entropy_weighter.html +++ /dev/null @@ -1,1287 +0,0 @@ ---- - -title: Create multi-task adjustment for cross-entropy - - -keywords: fastai -sidebar: home_sidebar - -summary: "A weighter for multi-task learning with different softmax+cross-entropy" -description: "A weighter for multi-task learning with different softmax+cross-entropy" -nb_path: "nbs/cross_entropy_weighter.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - -
-
-

Tools and imports

-
-
-
- {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
from matplotlib import pyplot as plt
-
- -
-
-
- -
- {% endraw %} - -
-
-

Enters softmax

-
-
-
- {% raw %} - -
-
- -
-
-
softmax = nn.Softmax(-1)
-crit = nn.CrossEntropyLoss()
-
- -
-
-
- -
- {% endraw %} - -
-
-

Experience the problem

-
-
-
- {% raw %} - -
-
- -
-
-
def test_loss(model,iters:300,get_xy):
-    losses=[]
-    with torch.no_grad():
-        for i in range(iters):
-            x,y_true = get_xy(model.nb_output)
-            y_vec = model(x)
-            loss = model.crit(y_vec,y_true)
-            losses.append(loss)
-    return torch.stack(losses).mean()
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
def create_softmax_pipeline(
-        nb_layers:int,
-        nb_output:int,
-        hs:int=500,
-        crit:nn.Module=nn.CrossEntropyLoss(),
-    )->nn.Module:
-    modules = (nb_layers-1)*[nn.Linear(hs,hs),nn.Dropout(.3)]
-    modules+=[nn.Linear(hs,nb_output),]
-    model = nn.Sequential(*modules)
-    model.hs = hs
-    model.nb_output = nb_output
-    model.__class__.crit = crit
-    model.__class__.test_loss = test_loss
-    return model
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
def random_input(nb_output):
-    return torch.rand(2,500),torch.randint(low=0,high=nb_output,size = (2,))
-
-def inbalanced_input(
-        bias:float
-    ) -> Callable:
-    def inbalanced_input_(nb_output:int):
-        return torch.rand(2,500),torch.randint(
-            low=0,
-            high=max(1,int(nb_output*bias)),
-            size = (2,)
-        )
-    return inbalanced_input_
-
- -
-
-
- -
- {% endraw %} - -
-
-
    -
  • For models with different branches of output, some output 2 category, some output more, like 200,500
  • -
  • Their loss will end up in different scale
  • -
  • That makes mixing them up fairly hard and unfair to lesser category tasks
  • -
- -
-
-
- {% raw %} - -
-
- -
-
-
import random
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
result = []
-
-for i in tqdm(range(50)):
-    c = random.randint(2,3000)
-    b = 1-random.random()
-    loss = create_softmax_pipeline(1,c).test_loss(300,inbalanced_input(b))
-    result.append(dict(classes=c,loss=loss.item(),inbl_bias=b))
-
- -
-
-
- -
-
- -
- -
-
-
-
-
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df = pd.DataFrame(result)
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
classeslossinbl_bias
022447.7840150.719190
124477.8491580.002960
27066.6254160.297956
32725.7390010.154829
428607.9948820.179631
523767.8230360.554090
64746.2306430.497769
714767.3176500.790722
87296.6523120.671657
911837.1610010.422553
1017927.5710340.375524
1126017.9283470.937953
1219887.6534010.448365
136176.4717110.669720
1412577.1966650.180724
1512087.1422720.603882
1615717.4319090.307233
1718157.5657630.271957
1823707.8402560.130841
1924217.8353620.470347
2026087.9338520.362477
2118337.5664140.551423
2217697.5360470.630381
2319507.6157930.795910
2419107.5857390.343632
2523017.7984650.829628
2623777.8692110.016988
2714967.3931780.119690
2811797.1470580.568997
2914757.3567400.693435
3024097.8359540.455461
315426.3284030.733283
326996.6098920.674927
3329668.0627700.268944
3428318.0060010.822981
3516577.4594730.323996
3614697.3166780.062805
376746.5796550.812632
386546.5500600.601652
391945.3505550.238536
402505.5670150.270642
4123687.8191310.117133
4215737.4296060.003537
4329948.0539260.764925
4421557.7413450.941843
4526427.9191260.612718
464866.2425270.701243
4719487.6443660.970036
4826267.9323630.657842
4916607.4668120.855916
-
-
- -
- -
-
- -
- {% endraw %} - -
-
-

The pattern

-
-
-
-
-
-

There are $n$ tasks $T$ with a set of numbers of classes $C$ where $c_{i}$ is the number of the classes of task $T_{i}$

-

The number of classes $c_{i}$ has certain correlation of the average loss $L_{i}$

-

Where $log_{10}(c_{i})$ has a clear linear relationship with $L$

-

$L_{i} = a.log_{10}(c_{i})$, where a is a fixed constant

- -
-
-
- {% raw %} - -
-
- -
-
-
plt.scatter(np.log10(df.classes),df.loss,)
-
- -
-
-
- -
-
- -
- - - -
-
<matplotlib.collections.PathCollection at 0x132a9c210>
-
- -
- -
- - - -
- -
- -
- -
-
- -
- {% endraw %} - -
-
-

The solution

Assume we have certain function, will produce a weight that will bring each cross entropy loss to the same constant scale ${a}$.

-

$L_{i}.f(c_{i})=a$

-

$f(c_{i})a.log_{10}(c_{i})=a$

-

Here we can get how to calculate $f(c_{i})$

-

$f(c_{i})=\frac{1}{log_{10}(c_{i})}$

- -
-
-
- {% raw %} - -
-
- -
-
-
def adjust(nb_class):
-    return 1/np.log10(nb_class)
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df["lambda_weighted"] = df.apply(
-    lambda row:row['loss']*adjust(row['classes']),
-    axis=1)
-
- -
-
-
- -
- {% endraw %} - -
-
-

For now it's a about the same scale of loss

- -
-
-
- {% raw %} - -
-
- -
-
-
plt.scatter(df.classes,df.lambda_weighted)
-
- -
-
-
- -
-
- -
- - - -
-
<matplotlib.collections.PathCollection at 0x132a9c150>
-
- -
- -
- - - -
- -
- -
- -
-
- -
- {% endraw %} - -
-
-

Adjusted CrossEntropy

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

class MultiTaskCELoss[source]

MultiTaskCELoss() :: Module

-
-

A cross entropy loss function which will cancel out - the effect of different class numbers

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Let's make this adjustment into the loss function, an upgraded version of CrossEntropy

- -
-
-
- {% raw %} - -
-
- -
-
-
result = []
-
-for i in tqdm(range(50)):
-    c = random.randint(2,3000)
-    b = 1-random.random()
-    # here we change the loss function to MultiTaskCELoss
-    loss = create_softmax_pipeline(1,c,crit=MultiTaskCELoss())\
-        .test_loss(300,inbalanced_input(b))
-    result.append(dict(classes=c,loss=loss.item(),inbl_bias=b))
-
- -
-
-
- -
-
- -
- -
-
-
-
-
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df_adjusted = pd.DataFrame(result)
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df_adjusted
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
classeslossinbl_bias
05332.3192480.208584
122642.3263460.022896
22542.3207350.922445
310272.3282910.643444
424282.3261360.883795
57722.3170710.062716
621662.3157540.364122
78122.3219720.852977
826322.3217080.639467
925762.3132690.968200
1013262.3215150.508901
111692.3215260.870789
128152.3091630.262275
137922.3217710.608608
147392.3162150.198933
1524602.3185230.880343
1624202.3205170.781538
1716882.3166570.954598
1829292.3230090.750869
19782.1927230.089868
2016702.3256080.188055
2128682.3245250.058037
229052.3192830.126673
2316752.3095650.307769
2414302.3270990.451335
254242.3158440.512538
2615112.3163250.613963
279592.3303170.987407
281472.3254590.931882
292782.3172730.401440
308852.3253970.087088
3114592.3079710.857782
321822.3447160.443465
3324682.3268250.572978
349542.3227500.815261
3512972.3199340.887149
3617872.3261610.113759
374622.3252760.969307
386862.3242620.305557
394282.3239130.342770
4029002.3193490.609161
4127652.3233730.296973
427522.3201890.302571
435022.3258970.419716
4421622.3204490.202672
4524602.3179620.430931
4625372.3121160.693554
478062.3187460.539312
482512.3228450.181191
4928452.3260070.667570
-
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
plt.scatter(
-    df_adjusted.classes,
-    df_adjusted.loss,
-)
-
- -
-
-
- -
-
- -
- - - -
-
<matplotlib.collections.PathCollection at 0x131d00bd0>
-
- -
- -
- - - -
- -
- -
- -
-
- -
- {% endraw %} - -
- - diff --git a/docs/css/bootstrap.min.css b/docs/css/bootstrap.min.css deleted file mode 100755 index 783f60d..0000000 --- a/docs/css/bootstrap.min.css +++ /dev/null @@ -1,7535 +0,0 @@ -/*! - * Bootstrap v3.3.2 (http://getbootstrap.com) - * Copyright 2011-2016 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - - -/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ - -html { - font-family: sans-serif; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100% -} - -body { - margin: 0 -} - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -menu, -nav, -section, -summary { - display: block -} - -audio, -canvas, -progress, -video { - display: inline-block; - vertical-align: baseline -} - -audio:not([controls]) { - display: none; - height: 0 -} - -[hidden], -template { - display: none -} - -a { - background-color: transparent -} - -a:active, -a:hover { - outline: 0 -} - -abbr[title] { - border-bottom: 1px dotted -} - -b, -strong { - font-weight: 700 -} - -dfn { - font-style: italic -} - -h1 { - margin: .67em 0; - font-size: 2em -} - -mark { - color: #000; - background: #ff0 -} - -small { - font-size: 80% -} - -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline -} - -sup { - top: -.5em -} - -sub { - bottom: -.25em -} - -img { - border: 0 -} - -svg:not(:root) { - overflow: hidden -} - -figure { - margin: 1em 40px -} - -hr { - height: 0; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box -} - -pre { - overflow: auto -} - -code, -kbd, -pre, -samp { - font-family: monospace, monospace; - font-size: 1em -} - -button, -input, -optgroup, -select, -textarea { - margin: 0; - font: inherit; - color: inherit -} - -button { - overflow: visible -} - -button, -select { - text-transform: none -} - -button, -html input[type=button], -input[type=reset], -input[type=submit] { - -webkit-appearance: button; - cursor: pointer -} - -button[disabled], -html input[disabled] { - cursor: default -} - -button::-moz-focus-inner, -input::-moz-focus-inner { - padding: 0; - border: 0 -} - -input { - line-height: normal -} - -input[type=checkbox], -input[type=radio] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 0 -} - -input[type=number]::-webkit-inner-spin-button, -input[type=number]::-webkit-outer-spin-button { - height: auto -} - -input[type=search] { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield -} - -input[type=search]::-webkit-search-cancel-button, -input[type=search]::-webkit-search-decoration { - -webkit-appearance: none -} - -fieldset { - padding: .35em .625em .75em; - margin: 0 2px; - border: 1px solid silver -} - -legend { - padding: 0; - border: 0 -} - -textarea { - overflow: auto -} - -optgroup { - font-weight: 700 -} - -table { - border-spacing: 0; - border-collapse: collapse -} - -td, -th { - padding: 0 -} - - -/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ - -@media print { - *, - :after, - :before { - /*color:#000!important;*/ - /*background:0 0!important*/ - ; - } - a, - a:visited { - text-decoration: underline - } - a[href]:after { - content: " (" attr(href) ")" - } - abbr[title]:after { - content: " (" attr(title) ")" - } - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: "" - } - blockquote, - pre { - border: 1px solid #999; - page-break-inside: avoid - } - thead { - display: table-header-group - } - img, - tr { - page-break-inside: avoid - } - img { - max-width: 100%!important - } - h2, - h3, - p { - orphans: 3; - widows: 3 - } - h2, - h3 { - page-break-after: avoid - } - select { - background: #fff!important - } - .navbar { - display: none - } - .btn>.caret, - .dropup>.btn>.caret { - border-top-color: #000!important - } - .label { - border: 1px solid #000 - } - .table { - border-collapse: collapse!important - } - .table td, - .table th { - background-color: #fff!important - } - .table-bordered td, - .table-bordered th { - border: 1px solid #ddd!important - } -} - -@font-face { - font-family: 'Glyphicons Halflings'; - src: url(../fonts/glyphicons-halflings-regular.eot); - src: url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'), url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'), url(../fonts/glyphicons-halflings-regular.woff) format('woff'), url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'), url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg') -} - -.glyphicon { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - font-style: normal; - font-weight: 400; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale -} - -.glyphicon-asterisk:before { - content: "\2a" -} - -.glyphicon-plus:before { - content: "\2b" -} - -.glyphicon-eur:before, -.glyphicon-euro:before { - content: "\20ac" -} - -.glyphicon-minus:before { - content: "\2212" -} - -.glyphicon-cloud:before { - content: "\2601" -} - -.glyphicon-envelope:before { - content: "\2709" -} - -.glyphicon-pencil:before { - content: "\270f" -} - -.glyphicon-glass:before { - content: "\e001" -} - -.glyphicon-music:before { - content: "\e002" -} - -.glyphicon-search:before { - content: "\e003" -} - -.glyphicon-heart:before { - content: "\e005" -} - -.glyphicon-star:before { - content: "\e006" -} - -.glyphicon-star-empty:before { - content: "\e007" -} - -.glyphicon-user:before { - content: "\e008" -} - -.glyphicon-film:before { - content: "\e009" -} - -.glyphicon-th-large:before { - content: "\e010" -} - -.glyphicon-th:before { - content: "\e011" -} - -.glyphicon-th-list:before { - content: "\e012" -} - -.glyphicon-ok:before { - content: "\e013" -} - -.glyphicon-remove:before { - content: "\e014" -} - -.glyphicon-zoom-in:before { - content: "\e015" -} - -.glyphicon-zoom-out:before { - content: "\e016" -} - -.glyphicon-off:before { - content: "\e017" -} - -.glyphicon-signal:before { - content: "\e018" -} - -.glyphicon-cog:before { - content: "\e019" -} - -.glyphicon-trash:before { - content: "\e020" -} - -.glyphicon-home:before { - content: "\e021" -} - -.glyphicon-file:before { - content: "\e022" -} - -.glyphicon-time:before { - content: "\e023" -} - -.glyphicon-road:before { - content: "\e024" -} - -.glyphicon-download-alt:before { - content: "\e025" -} - -.glyphicon-download:before { - content: "\e026" -} - -.glyphicon-upload:before { - content: "\e027" -} - -.glyphicon-inbox:before { - content: "\e028" -} - -.glyphicon-play-circle:before { - content: "\e029" -} - -.glyphicon-repeat:before { - content: "\e030" -} - -.glyphicon-refresh:before { - content: "\e031" -} - -.glyphicon-list-alt:before { - content: "\e032" -} - -.glyphicon-lock:before { - content: "\e033" -} - -.glyphicon-flag:before { - content: "\e034" -} - -.glyphicon-headphones:before { - content: "\e035" -} - -.glyphicon-volume-off:before { - content: "\e036" -} - -.glyphicon-volume-down:before { - content: "\e037" -} - -.glyphicon-volume-up:before { - content: "\e038" -} - -.glyphicon-qrcode:before { - content: "\e039" -} - -.glyphicon-barcode:before { - content: "\e040" -} - -.glyphicon-tag:before { - content: "\e041" -} - -.glyphicon-tags:before { - content: "\e042" -} - -.glyphicon-book:before { - content: "\e043" -} - -.glyphicon-bookmark:before { - content: "\e044" -} - -.glyphicon-print:before { - content: "\e045" -} - -.glyphicon-camera:before { - content: "\e046" -} - -.glyphicon-font:before { - content: "\e047" -} - -.glyphicon-bold:before { - content: "\e048" -} - -.glyphicon-italic:before { - content: "\e049" -} - -.glyphicon-text-height:before { - content: "\e050" -} - -.glyphicon-text-width:before { - content: "\e051" -} - -.glyphicon-align-left:before { - content: "\e052" -} - -.glyphicon-align-center:before { - content: "\e053" -} - -.glyphicon-align-right:before { - content: "\e054" -} - -.glyphicon-align-justify:before { - content: "\e055" -} - -.glyphicon-list:before { - content: "\e056" -} - -.glyphicon-indent-left:before { - content: "\e057" -} - -.glyphicon-indent-right:before { - content: "\e058" -} - -.glyphicon-facetime-video:before { - content: "\e059" -} - -.glyphicon-picture:before { - content: "\e060" -} - -.glyphicon-map-marker:before { - content: "\e062" -} - -.glyphicon-adjust:before { - content: "\e063" -} - -.glyphicon-tint:before { - content: "\e064" -} - -.glyphicon-edit:before { - content: "\e065" -} - -.glyphicon-share:before { - content: "\e066" -} - -.glyphicon-check:before { - content: "\e067" -} - -.glyphicon-move:before { - content: "\e068" -} - -.glyphicon-step-backward:before { - content: "\e069" -} - -.glyphicon-fast-backward:before { - content: "\e070" -} - -.glyphicon-backward:before { - content: "\e071" -} - -.glyphicon-play:before { - content: "\e072" -} - -.glyphicon-pause:before { - content: "\e073" -} - -.glyphicon-stop:before { - content: "\e074" -} - -.glyphicon-forward:before { - content: "\e075" -} - -.glyphicon-fast-forward:before { - content: "\e076" -} - -.glyphicon-step-forward:before { - content: "\e077" -} - -.glyphicon-eject:before { - content: "\e078" -} - -.glyphicon-chevron-left:before { - content: "\e079" -} - -.glyphicon-chevron-right:before { - content: "\e080" -} - -.glyphicon-plus-sign:before { - content: "\e081" -} - -.glyphicon-minus-sign:before { - content: "\e082" -} - -.glyphicon-remove-sign:before { - content: "\e083" -} - -.glyphicon-ok-sign:before { - content: "\e084" -} - -.glyphicon-question-sign:before { - content: "\e085" -} - -.glyphicon-info-sign:before { - content: "\e086" -} - -.glyphicon-screenshot:before { - content: "\e087" -} - -.glyphicon-remove-circle:before { - content: "\e088" -} - -.glyphicon-ok-circle:before { - content: "\e089" -} - -.glyphicon-ban-circle:before { - content: "\e090" -} - -.glyphicon-arrow-left:before { - content: "\e091" -} - -.glyphicon-arrow-right:before { - content: "\e092" -} - -.glyphicon-arrow-up:before { - content: "\e093" -} - -.glyphicon-arrow-down:before { - content: "\e094" -} - -.glyphicon-share-alt:before { - content: "\e095" -} - -.glyphicon-resize-full:before { - content: "\e096" -} - -.glyphicon-resize-small:before { - content: "\e097" -} - -.glyphicon-exclamation-sign:before { - content: "\e101" -} - -.glyphicon-gift:before { - content: "\e102" -} - -.glyphicon-leaf:before { - content: "\e103" -} - -.glyphicon-fire:before { - content: "\e104" -} - -.glyphicon-eye-open:before { - content: "\e105" -} - -.glyphicon-eye-close:before { - content: "\e106" -} - -.glyphicon-warning-sign:before { - content: "\e107" -} - -.glyphicon-plane:before { - content: "\e108" -} - -.glyphicon-calendar:before { - content: "\e109" -} - -.glyphicon-random:before { - content: "\e110" -} - -.glyphicon-comment:before { - content: "\e111" -} - -.glyphicon-magnet:before { - content: "\e112" -} - -.glyphicon-chevron-up:before { - content: "\e113" -} - -.glyphicon-chevron-down:before { - content: "\e114" -} - -.glyphicon-retweet:before { - content: "\e115" -} - -.glyphicon-shopping-cart:before { - content: "\e116" -} - -.glyphicon-folder-close:before { - content: "\e117" -} - -.glyphicon-folder-open:before { - content: "\e118" -} - -.glyphicon-resize-vertical:before { - content: "\e119" -} - -.glyphicon-resize-horizontal:before { - content: "\e120" -} - -.glyphicon-hdd:before { - content: "\e121" -} - -.glyphicon-bullhorn:before { - content: "\e122" -} - -.glyphicon-bell:before { - content: "\e123" -} - -.glyphicon-certificate:before { - content: "\e124" -} - -.glyphicon-thumbs-up:before { - content: "\e125" -} - -.glyphicon-thumbs-down:before { - content: "\e126" -} - -.glyphicon-hand-right:before { - content: "\e127" -} - -.glyphicon-hand-left:before { - content: "\e128" -} - -.glyphicon-hand-up:before { - content: "\e129" -} - -.glyphicon-hand-down:before { - content: "\e130" -} - -.glyphicon-circle-arrow-right:before { - content: "\e131" -} - -.glyphicon-circle-arrow-left:before { - content: "\e132" -} - -.glyphicon-circle-arrow-up:before { - content: "\e133" -} - -.glyphicon-circle-arrow-down:before { - content: "\e134" -} - -.glyphicon-globe:before { - content: "\e135" -} - -.glyphicon-wrench:before { - content: "\e136" -} - -.glyphicon-tasks:before { - content: "\e137" -} - -.glyphicon-filter:before { - content: "\e138" -} - -.glyphicon-briefcase:before { - content: "\e139" -} - -.glyphicon-fullscreen:before { - content: "\e140" -} - -.glyphicon-dashboard:before { - content: "\e141" -} - -.glyphicon-paperclip:before { - content: "\e142" -} - -.glyphicon-heart-empty:before { - content: "\e143" -} - -.glyphicon-link:before { - content: "\e144" -} - -.glyphicon-phone:before { - content: "\e145" -} - -.glyphicon-pushpin:before { - content: "\e146" -} - -.glyphicon-usd:before { - content: "\e148" -} - -.glyphicon-gbp:before { - content: "\e149" -} - -.glyphicon-sort:before { - content: "\e150" -} - -.glyphicon-sort-by-alphabet:before { - content: "\e151" -} - -.glyphicon-sort-by-alphabet-alt:before { - content: "\e152" -} - -.glyphicon-sort-by-order:before { - content: "\e153" -} - -.glyphicon-sort-by-order-alt:before { - content: "\e154" -} - -.glyphicon-sort-by-attributes:before { - content: "\e155" -} - -.glyphicon-sort-by-attributes-alt:before { - content: "\e156" -} - -.glyphicon-unchecked:before { - content: "\e157" -} - -.glyphicon-expand:before { - content: "\e158" -} - -.glyphicon-collapse-down:before { - content: "\e159" -} - -.glyphicon-collapse-up:before { - content: "\e160" -} - -.glyphicon-log-in:before { - content: "\e161" -} - -.glyphicon-flash:before { - content: "\e162" -} - -.glyphicon-log-out:before { - content: "\e163" -} - -.glyphicon-new-window:before { - content: "\e164" -} - -.glyphicon-record:before { - content: "\e165" -} - -.glyphicon-save:before { - content: "\e166" -} - -.glyphicon-open:before { - content: "\e167" -} - -.glyphicon-saved:before { - content: "\e168" -} - -.glyphicon-import:before { - content: "\e169" -} - -.glyphicon-export:before { - content: "\e170" -} - -.glyphicon-send:before { - content: "\e171" -} - -.glyphicon-floppy-disk:before { - content: "\e172" -} - -.glyphicon-floppy-saved:before { - content: "\e173" -} - -.glyphicon-floppy-remove:before { - content: "\e174" -} - -.glyphicon-floppy-save:before { - content: "\e175" -} - -.glyphicon-floppy-open:before { - content: "\e176" -} - -.glyphicon-credit-card:before { - content: "\e177" -} - -.glyphicon-transfer:before { - content: "\e178" -} - -.glyphicon-cutlery:before { - content: "\e179" -} - -.glyphicon-header:before { - content: "\e180" -} - -.glyphicon-compressed:before { - content: "\e181" -} - -.glyphicon-earphone:before { - content: "\e182" -} - -.glyphicon-phone-alt:before { - content: "\e183" -} - -.glyphicon-tower:before { - content: "\e184" -} - -.glyphicon-stats:before { - content: "\e185" -} - -.glyphicon-sd-video:before { - content: "\e186" -} - -.glyphicon-hd-video:before { - content: "\e187" -} - -.glyphicon-subtitles:before { - content: "\e188" -} - -.glyphicon-sound-stereo:before { - content: "\e189" -} - -.glyphicon-sound-dolby:before { - content: "\e190" -} - -.glyphicon-sound-5-1:before { - content: "\e191" -} - -.glyphicon-sound-6-1:before { - content: "\e192" -} - -.glyphicon-sound-7-1:before { - content: "\e193" -} - -.glyphicon-copyright-mark:before { - content: "\e194" -} - -.glyphicon-registration-mark:before { - content: "\e195" -} - -.glyphicon-cloud-download:before { - content: "\e197" -} - -.glyphicon-cloud-upload:before { - content: "\e198" -} - -.glyphicon-tree-conifer:before { - content: "\e199" -} - -.glyphicon-tree-deciduous:before { - content: "\e200" -} - -.glyphicon-cd:before { - content: "\e201" -} - -.glyphicon-save-file:before { - content: "\e202" -} - -.glyphicon-open-file:before { - content: "\e203" -} - -.glyphicon-level-up:before { - content: "\e204" -} - -.glyphicon-copy:before { - content: "\e205" -} - -.glyphicon-paste:before { - content: "\e206" -} - -.glyphicon-alert:before { - content: "\e209" -} - -.glyphicon-equalizer:before { - content: "\e210" -} - -.glyphicon-king:before { - content: "\e211" -} - -.glyphicon-queen:before { - content: "\e212" -} - -.glyphicon-pawn:before { - content: "\e213" -} - -.glyphicon-bishop:before { - content: "\e214" -} - -.glyphicon-knight:before { - content: "\e215" -} - -.glyphicon-baby-formula:before { - content: "\e216" -} - -.glyphicon-tent:before { - content: "\26fa" -} - -.glyphicon-blackboard:before { - content: "\e218" -} - -.glyphicon-bed:before { - content: "\e219" -} - -.glyphicon-apple:before { - content: "\f8ff" -} - -.glyphicon-erase:before { - content: "\e221" -} - -.glyphicon-hourglass:before { - content: "\231b" -} - -.glyphicon-lamp:before { - content: "\e223" -} - -.glyphicon-duplicate:before { - content: "\e224" -} - -.glyphicon-piggy-bank:before { - content: "\e225" -} - -.glyphicon-scissors:before { - content: "\e226" -} - -.glyphicon-bitcoin:before { - content: "\e227" -} - -.glyphicon-yen:before { - content: "\00a5" -} - -.glyphicon-ruble:before { - content: "\20bd" -} - -.glyphicon-scale:before { - content: "\e230" -} - -.glyphicon-ice-lolly:before { - content: "\e231" -} - -.glyphicon-ice-lolly-tasted:before { - content: "\e232" -} - -.glyphicon-education:before { - content: "\e233" -} - -.glyphicon-option-horizontal:before { - content: "\e234" -} - -.glyphicon-option-vertical:before { - content: "\e235" -} - -.glyphicon-menu-hamburger:before { - content: "\e236" -} - -.glyphicon-modal-window:before { - content: "\e237" -} - -.glyphicon-oil:before { - content: "\e238" -} - -.glyphicon-grain:before { - content: "\e239" -} - -.glyphicon-sunglasses:before { - content: "\e240" -} - -.glyphicon-text-size:before { - content: "\e241" -} - -.glyphicon-text-color:before { - content: "\e242" -} - -.glyphicon-text-background:before { - content: "\e243" -} - -.glyphicon-object-align-top:before { - content: "\e244" -} - -.glyphicon-object-align-bottom:before { - content: "\e245" -} - -.glyphicon-object-align-horizontal:before { - content: "\e246" -} - -.glyphicon-object-align-left:before { - content: "\e247" -} - -.glyphicon-object-align-vertical:before { - content: "\e248" -} - -.glyphicon-object-align-right:before { - content: "\e249" -} - -.glyphicon-triangle-right:before { - content: "\e250" -} - -.glyphicon-triangle-left:before { - content: "\e251" -} - -.glyphicon-triangle-bottom:before { - content: "\e252" -} - -.glyphicon-triangle-top:before { - content: "\e253" -} - -.glyphicon-console:before { - content: "\e254" -} - -.glyphicon-superscript:before { - content: "\e255" -} - -.glyphicon-subscript:before { - content: "\e256" -} - -.glyphicon-menu-left:before { - content: "\e257" -} - -.glyphicon-menu-right:before { - content: "\e258" -} - -.glyphicon-menu-down:before { - content: "\e259" -} - -.glyphicon-menu-up:before { - content: "\e260" -} - -* { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box -} - -:after, -:before { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box -} - -html { - font-size: 10px; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0) -} - -body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - line-height: 1.42857143; - color: #333; - background-color: #fff -} - -button, -input, -select, -textarea { - font-family: inherit; - font-size: inherit; - line-height: inherit -} - -a { - color: #337ab7; - text-decoration: none -} - -a:focus, -a:hover { - color: #23527c; - text-decoration: underline -} - -a:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px -} - -figure { - margin: 0 -} - -img { - vertical-align: middle -} - -.carousel-inner>.item>a>img, -.carousel-inner>.item>img, -.img-responsive, -.thumbnail a>img, -.thumbnail>img { - display: block; - max-width: 100%; - height: auto -} - -.img-rounded { - border-radius: 6px -} - -.img-thumbnail { - display: inline-block; - max-width: 100%; - height: auto; - padding: 4px; - line-height: 1.42857143; - background-color: #fff; - border: 1px solid #ddd; - border-radius: 4px; - -webkit-transition: all .2s ease-in-out; - -o-transition: all .2s ease-in-out; - transition: all .2s ease-in-out -} - -.img-circle { - border-radius: 50% -} - -hr { - margin-top: 20px; - margin-bottom: 20px; - border: 0; - border-top: 1px solid #eee -} - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0 -} - -.sr-only-focusable:active, -.sr-only-focusable:focus { - position: static; - width: auto; - height: auto; - margin: 0; - overflow: visible; - clip: auto -} - -.h1, -.h2, -.h3, -.h4, -.h5, -.h6, -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: inherit; - font-weight: 500; - line-height: 1.1; - color: inherit -} - -.h1 .small, -.h1 small, -.h2 .small, -.h2 small, -.h3 .small, -.h3 small, -.h4 .small, -.h4 small, -.h5 .small, -.h5 small, -.h6 .small, -.h6 small, -h1 .small, -h1 small, -h2 .small, -h2 small, -h3 .small, -h3 small, -h4 .small, -h4 small, -h5 .small, -h5 small, -h6 .small, -h6 small { - font-weight: 400; - line-height: 1; - color: #777 -} - -.h1, -.h2, -.h3, -h1, -h2, -h3 { - margin-top: 20px; - margin-bottom: 10px -} - -.h1 .small, -.h1 small, -.h2 .small, -.h2 small, -.h3 .small, -.h3 small, -h1 .small, -h1 small, -h2 .small, -h2 small, -h3 .small, -h3 small { - font-size: 65% -} - -.h4, -.h5, -.h6, -h4, -h5, -h6 { - margin-top: 10px; - margin-bottom: 10px -} - -.h4 .small, -.h4 small, -.h5 .small, -.h5 small, -.h6 .small, -.h6 small, -h4 .small, -h4 small, -h5 .small, -h5 small, -h6 .small, -h6 small { - font-size: 75% -} - -.h1, -h1 { - font-size: 36px -} - -.h2, -h2 { - font-size: 30px -} - -.h3, -h3 { - font-size: 24px -} - -.h4, -h4 { - font-size: 18px -} - -.h5, -h5 { - font-size: 14px -} - -.h6, -h6 { - font-size: 12px -} - -p { - margin: 0 0 10px -} - -.lead { - margin-bottom: 20px; - font-size: 16px; - font-weight: 300; - line-height: 1.4 -} - -@media (min-width:768px) { - .lead { - font-size: 21px - } -} - -.small, -small { - font-size: 85% -} - -.mark, -mark { - padding: .2em; - background-color: #fcf8e3 -} - -.text-left { - text-align: left -} - -.text-right { - text-align: right -} - -.text-center { - text-align: center -} - -.text-justify { - text-align: justify -} - -.text-nowrap { - white-space: nowrap -} - -.text-lowercase { - text-transform: lowercase -} - -.text-uppercase { - text-transform: uppercase -} - -.text-capitalize { - text-transform: capitalize -} - -.text-muted { - color: #777 -} - -.text-primary { - color: #337ab7 -} - -a.text-primary:hover { - color: #286090 -} - -.text-success { - color: #3c763d -} - -a.text-success:hover { - color: #2b542c -} - -.text-info { - color: #31708f -} - -a.text-info:hover { - color: #245269 -} - -.text-warning { - color: #8a6d3b -} - -a.text-warning:hover { - color: #66512c -} - -.text-danger { - color: #a94442 -} - -a.text-danger:hover { - color: #843534 -} - -.bg-primary { - color: #fff; - background-color: #337ab7 -} - -a.bg-primary:hover { - background-color: #286090 -} - -.bg-success { - background-color: #dff0d8 -} - -a.bg-success:hover { - background-color: #c1e2b3 -} - -.bg-info { - background-color: #d9edf7 -} - -a.bg-info:hover { - background-color: #afd9ee -} - -.bg-warning { - background-color: #fcf8e3 -} - -a.bg-warning:hover { - background-color: #f7ecb5 -} - -.bg-danger { - background-color: #f2dede -} - -a.bg-danger:hover { - background-color: #e4b9b9 -} - -.page-header { - padding-bottom: 9px; - margin: 40px 0 20px; - border-bottom: 1px solid #eee -} - -ol, -ul { - margin-top: 0; - margin-bottom: 10px -} - -ol ol, -ol ul, -ul ol, -ul ul { - margin-bottom: 0 -} - -.list-unstyled { - padding-left: 0; - list-style: none -} - -.list-inline { - padding-left: 0; - margin-left: -5px; - list-style: none -} - -.list-inline>li { - display: inline-block; - padding-right: 5px; - padding-left: 5px -} - -dl { - margin-top: 0; - margin-bottom: 20px -} - -dd, -dt { - line-height: 1.42857143 -} - -dt { - font-weight: 700 -} - -dd { - margin-left: 0 -} - -@media (min-width:768px) { - .dl-horizontal dt { - float: left; - width: 160px; - overflow: hidden; - clear: left; - text-align: right; - text-overflow: ellipsis; - white-space: nowrap - } - .dl-horizontal dd { - margin-left: 180px - } -} - -abbr[data-original-title], -abbr[title] { - cursor: help; - border-bottom: 1px dotted #777 -} - -.initialism { - font-size: 90%; - text-transform: uppercase -} - -blockquote { - padding: 10px 20px; - margin: 0 0 20px; - font-size: 17.5px; - border-left: 5px solid #eee -} - -blockquote ol:last-child, -blockquote p:last-child, -blockquote ul:last-child { - margin-bottom: 0 -} - -blockquote .small, -blockquote footer, -blockquote small { - display: block; - font-size: 80%; - line-height: 1.42857143; - color: #777 -} - -blockquote .small:before, -blockquote footer:before, -blockquote small:before { - content: '\2014 \00A0' -} - -.blockquote-reverse, -blockquote.pull-right { - padding-right: 15px; - padding-left: 0; - text-align: right; - border-right: 5px solid #eee; - border-left: 0 -} - -.blockquote-reverse .small:before, -.blockquote-reverse footer:before, -.blockquote-reverse small:before, -blockquote.pull-right .small:before, -blockquote.pull-right footer:before, -blockquote.pull-right small:before { - content: '' -} - -.blockquote-reverse .small:after, -.blockquote-reverse footer:after, -.blockquote-reverse small:after, -blockquote.pull-right .small:after, -blockquote.pull-right footer:after, -blockquote.pull-right small:after { - content: '\00A0 \2014' -} - -address { - margin-bottom: 20px; - font-style: normal; - line-height: 1.42857143 -} - -code, -kbd, -pre, -samp, -ouput_html{ - font-family: Menlo, Monaco, Consolas, "Courier New", monospace -} - -code, -ouput_html{ - padding: 2px 4px; - font-size: 90%; - color: #c7254e; - background-color: #f9f2f4; - border-radius: 4px -} - -kbd { - padding: 2px 4px; - font-size: 90%; - color: #fff; - background-color: #333; - border-radius: 3px; -} - -kbd kbd { - padding: 0; - font-size: 100%; - font-weight: 700; -} - -pre, -output_html{ - display: block; - padding: 9.5px; - margin: 0 0 10px; - font-size: 13px; - line-height: 1.42857143; - color: #333; - word-break: break-all; - word-wrap: break-word; - background-color: #f5f5f5; - border: 1px solid #ccc; - border-radius: 4px -} - - -pre, -code, -output_html{ - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border-radius: 0 -} - -.pre-scrollable { - max-height: 340px; - overflow-y: scroll -} - -.container { - padding-right: 15px; - padding-left: 15px; - margin-right: auto; - margin-left: auto -} - -@media (min-width:768px) { - .container { - width: 750px - } -} - -@media (min-width:992px) { - .container { - width: 970px - } -} - -@media (min-width:1200px) { - .container { - width: 1170px - } -} - -.container-fluid { - padding-right: 15px; - padding-left: 15px; - margin-right: auto; - margin-left: auto -} - -.row { - margin-right: -15px; - margin-left: -15px -} - -.col-lg-1, -.col-lg-10, -.col-lg-11, -.col-lg-12, -.col-lg-2, -.col-lg-3, -.col-lg-4, -.col-lg-5, -.col-lg-6, -.col-lg-7, -.col-lg-8, -.col-lg-9, -.col-md-1, -.col-md-10, -.col-md-11, -.col-md-12, -.col-md-2, -.col-md-3, -.col-md-4, -.col-md-5, -.col-md-6, -.col-md-7, -.col-md-8, -.col-md-9, -.col-sm-1, -.col-sm-10, -.col-sm-11, -.col-sm-12, -.col-sm-2, -.col-sm-3, -.col-sm-4, -.col-sm-5, -.col-sm-6, -.col-sm-7, -.col-sm-8, -.col-sm-9, -.col-xs-1, -.col-xs-10, -.col-xs-11, -.col-xs-12, -.col-xs-2, -.col-xs-3, -.col-xs-4, -.col-xs-5, -.col-xs-6, -.col-xs-7, -.col-xs-8, -.col-xs-9 { - position: relative; - min-height: 1px; - padding-right: 15px; - padding-left: 15px -} - -.col-xs-1, -.col-xs-10, -.col-xs-11, -.col-xs-12, -.col-xs-2, -.col-xs-3, -.col-xs-4, -.col-xs-5, -.col-xs-6, -.col-xs-7, -.col-xs-8, -.col-xs-9 { - float: left -} - -.col-xs-12 { - width: 100% -} - -.col-xs-11 { - width: 91.66666667% -} - -.col-xs-10 { - width: 83.33333333% -} - -.col-xs-9 { - width: 75% -} - -.col-xs-8 { - width: 66.66666667% -} - -.col-xs-7 { - width: 58.33333333% -} - -.col-xs-6 { - width: 50% -} - -.col-xs-5 { - width: 41.66666667% -} - -.col-xs-4 { - width: 33.33333333% -} - -.col-xs-3 { - width: 25% -} - -.col-xs-2 { - width: 16.66666667% -} - -.col-xs-1 { - width: 8.33333333% -} - -.col-xs-pull-12 { - right: 100% -} - -.col-xs-pull-11 { - right: 91.66666667% -} - -.col-xs-pull-10 { - right: 83.33333333% -} - -.col-xs-pull-9 { - right: 75% -} - -.col-xs-pull-8 { - right: 66.66666667% -} - -.col-xs-pull-7 { - right: 58.33333333% -} - -.col-xs-pull-6 { - right: 50% -} - -.col-xs-pull-5 { - right: 41.66666667% -} - -.col-xs-pull-4 { - right: 33.33333333% -} - -.col-xs-pull-3 { - right: 25% -} - -.col-xs-pull-2 { - right: 16.66666667% -} - -.col-xs-pull-1 { - right: 8.33333333% -} - -.col-xs-pull-0 { - right: auto -} - -.col-xs-push-12 { - left: 100% -} - -.col-xs-push-11 { - left: 91.66666667% -} - -.col-xs-push-10 { - left: 83.33333333% -} - -.col-xs-push-9 { - left: 75% -} - -.col-xs-push-8 { - left: 66.66666667% -} - -.col-xs-push-7 { - left: 58.33333333% -} - -.col-xs-push-6 { - left: 50% -} - -.col-xs-push-5 { - left: 41.66666667% -} - -.col-xs-push-4 { - left: 33.33333333% -} - -.col-xs-push-3 { - left: 25% -} - -.col-xs-push-2 { - left: 16.66666667% -} - -.col-xs-push-1 { - left: 8.33333333% -} - -.col-xs-push-0 { - left: auto -} - -.col-xs-offset-12 { - margin-left: 100% -} - -.col-xs-offset-11 { - margin-left: 91.66666667% -} - -.col-xs-offset-10 { - margin-left: 83.33333333% -} - -.col-xs-offset-9 { - margin-left: 75% -} - -.col-xs-offset-8 { - margin-left: 66.66666667% -} - -.col-xs-offset-7 { - margin-left: 58.33333333% -} - -.col-xs-offset-6 { - margin-left: 50% -} - -.col-xs-offset-5 { - margin-left: 41.66666667% -} - -.col-xs-offset-4 { - margin-left: 33.33333333% -} - -.col-xs-offset-3 { - margin-left: 25% -} - -.col-xs-offset-2 { - margin-left: 16.66666667% -} - -.col-xs-offset-1 { - margin-left: 8.33333333% -} - -.col-xs-offset-0 { - margin-left: 0 -} - -@media (min-width:768px) { - .col-sm-1, - .col-sm-10, - .col-sm-11, - .col-sm-12, - .col-sm-2, - .col-sm-3, - .col-sm-4, - .col-sm-5, - .col-sm-6, - .col-sm-7, - .col-sm-8, - .col-sm-9 { - float: left - } - .col-sm-12 { - width: 100% - } - .col-sm-11 { - width: 91.66666667% - } - .col-sm-10 { - width: 83.33333333% - } - .col-sm-9 { - width: 75% - } - .col-sm-8 { - width: 66.66666667% - } - .col-sm-7 { - width: 58.33333333% - } - .col-sm-6 { - width: 50% - } - .col-sm-5 { - width: 41.66666667% - } - .col-sm-4 { - width: 33.33333333% - } - .col-sm-3 { - width: 25% - } - .col-sm-2 { - width: 16.66666667% - } - .col-sm-1 { - width: 8.33333333% - } - .col-sm-pull-12 { - right: 100% - } - .col-sm-pull-11 { - right: 91.66666667% - } - .col-sm-pull-10 { - right: 83.33333333% - } - .col-sm-pull-9 { - right: 75% - } - .col-sm-pull-8 { - right: 66.66666667% - } - .col-sm-pull-7 { - right: 58.33333333% - } - .col-sm-pull-6 { - right: 50% - } - .col-sm-pull-5 { - right: 41.66666667% - } - .col-sm-pull-4 { - right: 33.33333333% - } - .col-sm-pull-3 { - right: 25% - } - .col-sm-pull-2 { - right: 16.66666667% - } - .col-sm-pull-1 { - right: 8.33333333% - } - .col-sm-pull-0 { - right: auto - } - .col-sm-push-12 { - left: 100% - } - .col-sm-push-11 { - left: 91.66666667% - } - .col-sm-push-10 { - left: 83.33333333% - } - .col-sm-push-9 { - left: 75% - } - .col-sm-push-8 { - left: 66.66666667% - } - .col-sm-push-7 { - left: 58.33333333% - } - .col-sm-push-6 { - left: 50% - } - .col-sm-push-5 { - left: 41.66666667% - } - .col-sm-push-4 { - left: 33.33333333% - } - .col-sm-push-3 { - left: 25% - } - .col-sm-push-2 { - left: 16.66666667% - } - .col-sm-push-1 { - left: 8.33333333% - } - .col-sm-push-0 { - left: auto - } - .col-sm-offset-12 { - margin-left: 100% - } - .col-sm-offset-11 { - margin-left: 91.66666667% - } - .col-sm-offset-10 { - margin-left: 83.33333333% - } - .col-sm-offset-9 { - margin-left: 75% - } - .col-sm-offset-8 { - margin-left: 66.66666667% - } - .col-sm-offset-7 { - margin-left: 58.33333333% - } - .col-sm-offset-6 { - margin-left: 50% - } - .col-sm-offset-5 { - margin-left: 41.66666667% - } - .col-sm-offset-4 { - margin-left: 33.33333333% - } - .col-sm-offset-3 { - margin-left: 25% - } - .col-sm-offset-2 { - margin-left: 16.66666667% - } - .col-sm-offset-1 { - margin-left: 8.33333333% - } - .col-sm-offset-0 { - margin-left: 0 - } -} - -@media (min-width:992px) { - .col-md-1, - .col-md-10, - .col-md-11, - .col-md-12, - .col-md-2, - .col-md-3, - .col-md-4, - .col-md-5, - .col-md-6, - .col-md-7, - .col-md-8, - .col-md-9 { - float: left - } - .col-md-12 { - width: 100% - } - .col-md-11 { - width: 91.66666667% - } - .col-md-10 { - width: 83.33333333% - } - .col-md-9 { - width: 75% - } - .col-md-8 { - width: 66.66666667% - } - .col-md-7 { - width: 58.33333333% - } - .col-md-6 { - width: 50% - } - .col-md-5 { - width: 41.66666667% - } - .col-md-4 { - width: 33.33333333% - } - .col-md-3 { - width: 25% - } - .col-md-2 { - width: 16.66666667% - } - .col-md-1 { - width: 8.33333333% - } - .col-md-pull-12 { - right: 100% - } - .col-md-pull-11 { - right: 91.66666667% - } - .col-md-pull-10 { - right: 83.33333333% - } - .col-md-pull-9 { - right: 75% - } - .col-md-pull-8 { - right: 66.66666667% - } - .col-md-pull-7 { - right: 58.33333333% - } - .col-md-pull-6 { - right: 50% - } - .col-md-pull-5 { - right: 41.66666667% - } - .col-md-pull-4 { - right: 33.33333333% - } - .col-md-pull-3 { - right: 25% - } - .col-md-pull-2 { - right: 16.66666667% - } - .col-md-pull-1 { - right: 8.33333333% - } - .col-md-pull-0 { - right: auto - } - .col-md-push-12 { - left: 100% - } - .col-md-push-11 { - left: 91.66666667% - } - .col-md-push-10 { - left: 83.33333333% - } - .col-md-push-9 { - left: 75% - } - .col-md-push-8 { - left: 66.66666667% - } - .col-md-push-7 { - left: 58.33333333% - } - .col-md-push-6 { - left: 50% - } - .col-md-push-5 { - left: 41.66666667% - } - .col-md-push-4 { - left: 33.33333333% - } - .col-md-push-3 { - left: 25% - } - .col-md-push-2 { - left: 16.66666667% - } - .col-md-push-1 { - left: 8.33333333% - } - .col-md-push-0 { - left: auto - } - .col-md-offset-12 { - margin-left: 100% - } - .col-md-offset-11 { - margin-left: 91.66666667% - } - .col-md-offset-10 { - margin-left: 83.33333333% - } - .col-md-offset-9 { - margin-left: 75% - } - .col-md-offset-8 { - margin-left: 66.66666667% - } - .col-md-offset-7 { - margin-left: 58.33333333% - } - .col-md-offset-6 { - margin-left: 50% - } - .col-md-offset-5 { - margin-left: 41.66666667% - } - .col-md-offset-4 { - margin-left: 33.33333333% - } - .col-md-offset-3 { - margin-left: 25% - } - .col-md-offset-2 { - margin-left: 16.66666667% - } - .col-md-offset-1 { - margin-left: 8.33333333% - } - .col-md-offset-0 { - margin-left: 0 - } -} - -@media (min-width:1200px) { - .col-lg-1, - .col-lg-10, - .col-lg-11, - .col-lg-12, - .col-lg-2, - .col-lg-3, - .col-lg-4, - .col-lg-5, - .col-lg-6, - .col-lg-7, - .col-lg-8, - .col-lg-9 { - float: left - } - .col-lg-12 { - width: 100% - } - .col-lg-11 { - width: 91.66666667% - } - .col-lg-10 { - width: 83.33333333% - } - .col-lg-9 { - width: 75% - } - .col-lg-8 { - width: 66.66666667% - } - .col-lg-7 { - width: 58.33333333% - } - .col-lg-6 { - width: 50% - } - .col-lg-5 { - width: 41.66666667% - } - .col-lg-4 { - width: 33.33333333% - } - .col-lg-3 { - width: 25% - } - .col-lg-2 { - width: 16.66666667% - } - .col-lg-1 { - width: 8.33333333% - } - .col-lg-pull-12 { - right: 100% - } - .col-lg-pull-11 { - right: 91.66666667% - } - .col-lg-pull-10 { - right: 83.33333333% - } - .col-lg-pull-9 { - right: 75% - } - .col-lg-pull-8 { - right: 66.66666667% - } - .col-lg-pull-7 { - right: 58.33333333% - } - .col-lg-pull-6 { - right: 50% - } - .col-lg-pull-5 { - right: 41.66666667% - } - .col-lg-pull-4 { - right: 33.33333333% - } - .col-lg-pull-3 { - right: 25% - } - .col-lg-pull-2 { - right: 16.66666667% - } - .col-lg-pull-1 { - right: 8.33333333% - } - .col-lg-pull-0 { - right: auto - } - .col-lg-push-12 { - left: 100% - } - .col-lg-push-11 { - left: 91.66666667% - } - .col-lg-push-10 { - left: 83.33333333% - } - .col-lg-push-9 { - left: 75% - } - .col-lg-push-8 { - left: 66.66666667% - } - .col-lg-push-7 { - left: 58.33333333% - } - .col-lg-push-6 { - left: 50% - } - .col-lg-push-5 { - left: 41.66666667% - } - .col-lg-push-4 { - left: 33.33333333% - } - .col-lg-push-3 { - left: 25% - } - .col-lg-push-2 { - left: 16.66666667% - } - .col-lg-push-1 { - left: 8.33333333% - } - .col-lg-push-0 { - left: auto - } - .col-lg-offset-12 { - margin-left: 100% - } - .col-lg-offset-11 { - margin-left: 91.66666667% - } - .col-lg-offset-10 { - margin-left: 83.33333333% - } - .col-lg-offset-9 { - margin-left: 75% - } - .col-lg-offset-8 { - margin-left: 66.66666667% - } - .col-lg-offset-7 { - margin-left: 58.33333333% - } - .col-lg-offset-6 { - margin-left: 50% - } - .col-lg-offset-5 { - margin-left: 41.66666667% - } - .col-lg-offset-4 { - margin-left: 33.33333333% - } - .col-lg-offset-3 { - margin-left: 25% - } - .col-lg-offset-2 { - margin-left: 16.66666667% - } - .col-lg-offset-1 { - margin-left: 8.33333333% - } - .col-lg-offset-0 { - margin-left: 0 - } -} - -table { - background-color: transparent -} - -caption { - padding-top: 8px; - padding-bottom: 8px; - color: #777; - text-align: left -} - -th { - text-align: left -} - -.table { - width: 100%; - max-width: 100%; - margin-bottom: 20px -} - -.table>tbody>tr>td, -.table>tbody>tr>th, -.table>tfoot>tr>td, -.table>tfoot>tr>th, -.table>thead>tr>td, -.table>thead>tr>th { - padding: 8px; - line-height: 1.42857143; - vertical-align: top; - border-top: 1px solid #ddd -} - -.table>thead>tr>th { - vertical-align: bottom; - border-bottom: 2px solid #ddd -} - -.table>caption+thead>tr:first-child>td, -.table>caption+thead>tr:first-child>th, -.table>colgroup+thead>tr:first-child>td, -.table>colgroup+thead>tr:first-child>th, -.table>thead:first-child>tr:first-child>td, -.table>thead:first-child>tr:first-child>th { - border-top: 0 -} - -.table>tbody+tbody { - border-top: 2px solid #ddd -} - -.table .table { - background-color: #fff -} - -.table-condensed>tbody>tr>td, -.table-condensed>tbody>tr>th, -.table-condensed>tfoot>tr>td, -.table-condensed>tfoot>tr>th, -.table-condensed>thead>tr>td, -.table-condensed>thead>tr>th { - padding: 5px -} - -.table-bordered { - border: 1px solid #ddd -} - -.table-bordered>tbody>tr>td, -.table-bordered>tbody>tr>th, -.table-bordered>tfoot>tr>td, -.table-bordered>tfoot>tr>th, -.table-bordered>thead>tr>td, -.table-bordered>thead>tr>th { - border: 1px solid #ddd -} - -.table-bordered>thead>tr>td, -.table-bordered>thead>tr>th { - border-bottom-width: 2px -} - -.table-striped>tbody>tr:nth-of-type(odd) { - background-color: #f9f9f9 -} - -.table-hover>tbody>tr:hover { - background-color: #f5f5f5 -} - -table col[class*=col-] { - position: static; - display: table-column; - float: none -} - -table td[class*=col-], -table th[class*=col-] { - position: static; - display: table-cell; - float: none -} - -.table>tbody>tr.active>td, -.table>tbody>tr.active>th, -.table>tbody>tr>td.active, -.table>tbody>tr>th.active, -.table>tfoot>tr.active>td, -.table>tfoot>tr.active>th, -.table>tfoot>tr>td.active, -.table>tfoot>tr>th.active, -.table>thead>tr.active>td, -.table>thead>tr.active>th, -.table>thead>tr>td.active, -.table>thead>tr>th.active { - background-color: #f5f5f5 -} - -.table-hover>tbody>tr.active:hover>td, -.table-hover>tbody>tr.active:hover>th, -.table-hover>tbody>tr:hover>.active, -.table-hover>tbody>tr>td.active:hover, -.table-hover>tbody>tr>th.active:hover { - background-color: #e8e8e8 -} - -.table>tbody>tr.success>td, -.table>tbody>tr.success>th, -.table>tbody>tr>td.success, -.table>tbody>tr>th.success, -.table>tfoot>tr.success>td, -.table>tfoot>tr.success>th, -.table>tfoot>tr>td.success, -.table>tfoot>tr>th.success, -.table>thead>tr.success>td, -.table>thead>tr.success>th, -.table>thead>tr>td.success, -.table>thead>tr>th.success { - background-color: #dff0d8 -} - -.table-hover>tbody>tr.success:hover>td, -.table-hover>tbody>tr.success:hover>th, -.table-hover>tbody>tr:hover>.success, -.table-hover>tbody>tr>td.success:hover, -.table-hover>tbody>tr>th.success:hover { - background-color: #d0e9c6 -} - -.table>tbody>tr.info>td, -.table>tbody>tr.info>th, -.table>tbody>tr>td.info, -.table>tbody>tr>th.info, -.table>tfoot>tr.info>td, -.table>tfoot>tr.info>th, -.table>tfoot>tr>td.info, -.table>tfoot>tr>th.info, -.table>thead>tr.info>td, -.table>thead>tr.info>th, -.table>thead>tr>td.info, -.table>thead>tr>th.info { - background-color: #d9edf7 -} - -.table-hover>tbody>tr.info:hover>td, -.table-hover>tbody>tr.info:hover>th, -.table-hover>tbody>tr:hover>.info, -.table-hover>tbody>tr>td.info:hover, -.table-hover>tbody>tr>th.info:hover { - background-color: #c4e3f3 -} - -.table>tbody>tr.warning>td, -.table>tbody>tr.warning>th, -.table>tbody>tr>td.warning, -.table>tbody>tr>th.warning, -.table>tfoot>tr.warning>td, -.table>tfoot>tr.warning>th, -.table>tfoot>tr>td.warning, -.table>tfoot>tr>th.warning, -.table>thead>tr.warning>td, -.table>thead>tr.warning>th, -.table>thead>tr>td.warning, -.table>thead>tr>th.warning { - background-color: #fcf8e3 -} - -.table-hover>tbody>tr.warning:hover>td, -.table-hover>tbody>tr.warning:hover>th, -.table-hover>tbody>tr:hover>.warning, -.table-hover>tbody>tr>td.warning:hover, -.table-hover>tbody>tr>th.warning:hover { - background-color: #faf2cc -} - -.table>tbody>tr.danger>td, -.table>tbody>tr.danger>th, -.table>tbody>tr>td.danger, -.table>tbody>tr>th.danger, -.table>tfoot>tr.danger>td, -.table>tfoot>tr.danger>th, -.table>tfoot>tr>td.danger, -.table>tfoot>tr>th.danger, -.table>thead>tr.danger>td, -.table>thead>tr.danger>th, -.table>thead>tr>td.danger, -.table>thead>tr>th.danger { - background-color: #f2dede -} - -.table-hover>tbody>tr.danger:hover>td, -.table-hover>tbody>tr.danger:hover>th, -.table-hover>tbody>tr:hover>.danger, -.table-hover>tbody>tr>td.danger:hover, -.table-hover>tbody>tr>th.danger:hover { - background-color: #ebcccc -} - -.table-responsive { - min-height: .01%; - overflow-x: auto -} - -@media screen and (max-width:767px) { - .table-responsive { - width: 100%; - margin-bottom: 15px; - overflow-y: hidden; - -ms-overflow-style: -ms-autohiding-scrollbar; - border: 1px solid #ddd - } - .table-responsive>.table { - margin-bottom: 0 - } - .table-responsive>.table>tbody>tr>td, - .table-responsive>.table>tbody>tr>th, - .table-responsive>.table>tfoot>tr>td, - .table-responsive>.table>tfoot>tr>th, - .table-responsive>.table>thead>tr>td, - .table-responsive>.table>thead>tr>th { - white-space: nowrap - } - .table-responsive>.table-bordered { - border: 0 - } - .table-responsive>.table-bordered>tbody>tr>td:first-child, - .table-responsive>.table-bordered>tbody>tr>th:first-child, - .table-responsive>.table-bordered>tfoot>tr>td:first-child, - .table-responsive>.table-bordered>tfoot>tr>th:first-child, - .table-responsive>.table-bordered>thead>tr>td:first-child, - .table-responsive>.table-bordered>thead>tr>th:first-child { - border-left: 0 - } - .table-responsive>.table-bordered>tbody>tr>td:last-child, - .table-responsive>.table-bordered>tbody>tr>th:last-child, - .table-responsive>.table-bordered>tfoot>tr>td:last-child, - .table-responsive>.table-bordered>tfoot>tr>th:last-child, - .table-responsive>.table-bordered>thead>tr>td:last-child, - .table-responsive>.table-bordered>thead>tr>th:last-child { - border-right: 0 - } - .table-responsive>.table-bordered>tbody>tr:last-child>td, - .table-responsive>.table-bordered>tbody>tr:last-child>th, - .table-responsive>.table-bordered>tfoot>tr:last-child>td, - .table-responsive>.table-bordered>tfoot>tr:last-child>th { - border-bottom: 0 - } -} - -fieldset { - min-width: 0; - padding: 0; - margin: 0; - border: 0 -} - -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 20px; - font-size: 21px; - line-height: inherit; - color: #333; - border: 0; - border-bottom: 1px solid #e5e5e5 -} - -label { - display: inline-block; - max-width: 100%; - margin-bottom: 5px; - font-weight: 700 -} - -input[type=search] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box -} - -input[type=checkbox], -input[type=radio] { - margin: 4px 0 0; - margin-top: 1px \9; - line-height: normal -} - -input[type=file] { - display: block -} - -input[type=range] { - display: block; - width: 100% -} - -select[multiple], -select[size] { - height: auto -} - -input[type=file]:focus, -input[type=checkbox]:focus, -input[type=radio]:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px -} - -output { - display: block; - padding-top: 7px; - font-size: 14px; - line-height: 1.42857143; - color: #555 -} - -.form-control { - display: block; - width: 100%; - height: 34px; - padding: 6px 12px; - font-size: 14px; - line-height: 1.42857143; - color: #555; - background-color: #fff; - background-image: none; - border: 1px solid #ccc; - border-radius: 4px; -} - -.form-control:focus { - border-color: #66afe9; - outline: 0; -} - -.form-control::-moz-placeholder { - color: #999; - opacity: 1 -} - -.form-control:-ms-input-placeholder { - color: #999 -} - -.form-control::-webkit-input-placeholder { - color: #999 -} - -.form-control[disabled], -.form-control[readonly], -fieldset[disabled] .form-control { - cursor: not-allowed; - background-color: #eee; - opacity: 1 -} - -textarea.form-control { - height: auto -} - -input[type=search] { - -webkit-appearance: none -} - -@media screen and (-webkit-min-device-pixel-ratio:0) { - input[type=date], - input[type=time], - input[type=datetime-local], - input[type=month] { - line-height: 34px - } - .input-group-sm input[type=date], - .input-group-sm input[type=time], - .input-group-sm input[type=datetime-local], - .input-group-sm input[type=month], - input[type=date].input-sm, - input[type=time].input-sm, - input[type=datetime-local].input-sm, - input[type=month].input-sm { - line-height: 30px - } - .input-group-lg input[type=date], - .input-group-lg input[type=time], - .input-group-lg input[type=datetime-local], - .input-group-lg input[type=month], - input[type=date].input-lg, - input[type=time].input-lg, - input[type=datetime-local].input-lg, - input[type=month].input-lg { - line-height: 46px - } -} - -.form-group { - margin-bottom: 15px -} - -.checkbox, -.radio { - position: relative; - display: block; - margin-top: 10px; - margin-bottom: 10px -} - -.checkbox label, -.radio label { - min-height: 20px; - padding-left: 20px; - margin-bottom: 0; - font-weight: 400; - cursor: pointer -} - -.checkbox input[type=checkbox], -.checkbox-inline input[type=checkbox], -.radio input[type=radio], -.radio-inline input[type=radio] { - position: absolute; - margin-top: 4px \9; - margin-left: -20px -} - -.checkbox+.checkbox, -.radio+.radio { - margin-top: -5px -} - -.checkbox-inline, -.radio-inline { - display: inline-block; - padding-left: 20px; - margin-bottom: 0; - font-weight: 400; - vertical-align: middle; - cursor: pointer -} - -.checkbox-inline+.checkbox-inline, -.radio-inline+.radio-inline { - margin-top: 0; - margin-left: 10px -} - -fieldset[disabled] input[type=checkbox], -fieldset[disabled] input[type=radio], -input[type=checkbox].disabled, -input[type=checkbox][disabled], -input[type=radio].disabled, -input[type=radio][disabled] { - cursor: not-allowed -} - -.checkbox-inline.disabled, -.radio-inline.disabled, -fieldset[disabled] .checkbox-inline, -fieldset[disabled] .radio-inline { - cursor: not-allowed -} - -.checkbox.disabled label, -.radio.disabled label, -fieldset[disabled] .checkbox label, -fieldset[disabled] .radio label { - cursor: not-allowed -} - -.form-control-static { - padding-top: 7px; - padding-bottom: 7px; - margin-bottom: 0 -} - -.form-control-static.input-lg, -.form-control-static.input-sm { - padding-right: 0; - padding-left: 0 -} - -.input-sm { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px -} - -select.input-sm { - height: 30px; - line-height: 30px -} - -select[multiple].input-sm, -textarea.input-sm { - height: auto -} - -.form-group-sm .form-control { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px -} - -select.form-group-sm .form-control { - height: 30px; - line-height: 30px -} - -select[multiple].form-group-sm .form-control, -textarea.form-group-sm .form-control { - height: auto -} - -.form-group-sm .form-control-static { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5 -} - -.input-lg { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.3333333; - border-radius: 6px -} - -select.input-lg { - height: 46px; - line-height: 46px -} - -select[multiple].input-lg, -textarea.input-lg { - height: auto -} - -.form-group-lg .form-control { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.3333333; - border-radius: 6px -} - -select.form-group-lg .form-control { - height: 46px; - line-height: 46px -} - -select[multiple].form-group-lg .form-control, -textarea.form-group-lg .form-control { - height: auto -} - -.form-group-lg .form-control-static { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.3333333 -} - -.has-feedback { - position: relative -} - -.has-feedback .form-control { - padding-right: 42.5px -} - -.form-control-feedback { - position: absolute; - top: 0; - right: 0; - z-index: 2; - display: block; - width: 34px; - height: 34px; - line-height: 34px; - text-align: center; -} - -.input-lg+.form-control-feedback { - width: 46px; - height: 46px; - line-height: 46px -} - -.input-sm+.form-control-feedback { - width: 30px; - height: 30px; - line-height: 30px -} - -.has-success .checkbox, -.has-success .checkbox-inline, -.has-success .control-label, -.has-success .help-block, -.has-success .radio, -.has-success .radio-inline, -.has-success.checkbox label, -.has-success.checkbox-inline label, -.has-success.radio label, -.has-success.radio-inline label { - color: #3c763d -} - -.has-success .form-control { - border-color: #3c763d; -} - -.has-success .form-control:focus { - border-color: #2b542c; -} - -.has-success .input-group-addon { - color: #3c763d; - background-color: #dff0d8; - border-color: #3c763d -} - -.has-success .form-control-feedback { - color: #3c763d -} - -.has-warning .checkbox, -.has-warning .checkbox-inline, -.has-warning .control-label, -.has-warning .help-block, -.has-warning .radio, -.has-warning .radio-inline, -.has-warning.checkbox label, -.has-warning.checkbox-inline label, -.has-warning.radio label, -.has-warning.radio-inline label { - color: #8a6d3b -} - -.has-warning .form-control { - border-color: #8a6d3b; -} - -.has-warning .form-control:focus { - border-color: #66512c; -} - -.has-warning .input-group-addon { - color: #8a6d3b; - background-color: #fcf8e3; - border-color: #8a6d3b -} - -.has-warning .form-control-feedback { - color: #8a6d3b -} - -.has-error .checkbox, -.has-error .checkbox-inline, -.has-error .control-label, -.has-error .help-block, -.has-error .radio, -.has-error .radio-inline, -.has-error.checkbox label, -.has-error.checkbox-inline label, -.has-error.radio label, -.has-error.radio-inline label { - color: #a94442 -} - -.has-error .form-control { - border-color: #a94442; -} - -.has-error .form-control:focus { - border-color: #843534; -} - -.has-error .input-group-addon { - color: #a94442; - background-color: #f2dede; - border-color: #a94442 -} - -.has-error .form-control-feedback { - color: #a94442 -} - -.has-feedback label~.form-control-feedback { - top: 25px -} - -.has-feedback label.sr-only~.form-control-feedback { - top: 0 -} - -.help-block { - display: block; - margin-top: 5px; - margin-bottom: 10px; - color: #737373 -} - -@media (min-width:768px) { - .form-inline .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle - } - .form-inline .form-control { - display: inline-block; - width: auto; - vertical-align: middle - } - .form-inline .form-control-static { - display: inline-block - } - .form-inline .input-group { - display: inline-table; - vertical-align: middle - } - .form-inline .input-group .form-control, - .form-inline .input-group .input-group-addon, - .form-inline .input-group .input-group-btn { - width: auto - } - .form-inline .input-group>.form-control { - width: 100% - } - .form-inline .control-label { - margin-bottom: 0; - vertical-align: middle - } - .form-inline .checkbox, - .form-inline .radio { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - vertical-align: middle - } - .form-inline .checkbox label, - .form-inline .radio label { - padding-left: 0 - } - .form-inline .checkbox input[type=checkbox], - .form-inline .radio input[type=radio] { - position: relative; - margin-left: 0 - } - .form-inline .has-feedback .form-control-feedback { - top: 0 - } -} - -.form-horizontal .checkbox, -.form-horizontal .checkbox-inline, -.form-horizontal .radio, -.form-horizontal .radio-inline { - padding-top: 7px; - margin-top: 0; - margin-bottom: 0 -} - -.form-horizontal .checkbox, -.form-horizontal .radio { - min-height: 27px -} - -.form-horizontal .form-group { - margin-right: -15px; - margin-left: -15px -} - -@media (min-width:768px) { - .form-horizontal .control-label { - padding-top: 7px; - margin-bottom: 0; - text-align: right - } -} - -.form-horizontal .has-feedback .form-control-feedback { - right: 15px -} - -@media (min-width:768px) { - .form-horizontal .form-group-lg .control-label { - padding-top: 14.33px - } -} - -@media (min-width:768px) { - .form-horizontal .form-group-sm .control-label { - padding-top: 6px - } -} - -.btn { - display: inline-block; - padding: 6px 12px; - margin-bottom: 0; - font-size: 14px; - font-weight: 400; - line-height: 1.42857143; - text-align: center; - white-space: nowrap; - vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-image: none; - border: 1px solid transparent; - border-radius: 4px -} - -.btn.active.focus, -.btn.active:focus, -.btn.focus, -.btn:active.focus, -.btn:active:focus, -.btn:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px -} - -.btn.focus, -.btn:focus, -.btn:hover { - color: #333; - text-decoration: none -} - -.btn.active, -.btn:active { - background-image: none; - outline: 0; -} - -.btn.disabled, -.btn[disabled], -fieldset[disabled] .btn { - cursor: not-allowed; - filter: alpha(opacity=65); - opacity: .65 -} - -.btn-default { - color: #333; - background-color: #fff; - border-color: #ccc -} - -.btn-default.active, -.btn-default.focus, -.btn-default:active, -.btn-default:focus, -.btn-default:hover, -.open>.dropdown-toggle.btn-default { - color: #333; - background-color: #e6e6e6; - border-color: #adadad -} - -.btn-default.active, -.btn-default:active, -.open>.dropdown-toggle.btn-default { - background-image: none -} - -.btn-default.disabled, -.btn-default.disabled.active, -.btn-default.disabled.focus, -.btn-default.disabled:active, -.btn-default.disabled:focus, -.btn-default.disabled:hover, -.btn-default[disabled], -.btn-default[disabled].active, -.btn-default[disabled].focus, -.btn-default[disabled]:active, -.btn-default[disabled]:focus, -.btn-default[disabled]:hover, -fieldset[disabled] .btn-default, -fieldset[disabled] .btn-default.active, -fieldset[disabled] .btn-default.focus, -fieldset[disabled] .btn-default:active, -fieldset[disabled] .btn-default:focus, -fieldset[disabled] .btn-default:hover { - background-color: #fff; - border-color: #ccc -} - -.btn-default .badge { - color: #fff; - background-color: #333 -} - -.btn-primary { - color: #fff; - background-color: #337ab7; - border-color: #2e6da4 -} - -.btn-primary.active, -.btn-primary.focus, -.btn-primary:active, -.btn-primary:focus, -.btn-primary:hover, -.open>.dropdown-toggle.btn-primary { - color: #fff; - background-color: #286090; - border-color: #204d74 -} - -.btn-primary.active, -.btn-primary:active, -.open>.dropdown-toggle.btn-primary { - background-image: none -} - -.btn-primary.disabled, -.btn-primary.disabled.active, -.btn-primary.disabled.focus, -.btn-primary.disabled:active, -.btn-primary.disabled:focus, -.btn-primary.disabled:hover, -.btn-primary[disabled], -.btn-primary[disabled].active, -.btn-primary[disabled].focus, -.btn-primary[disabled]:active, -.btn-primary[disabled]:focus, -.btn-primary[disabled]:hover, -fieldset[disabled] .btn-primary, -fieldset[disabled] .btn-primary.active, -fieldset[disabled] .btn-primary.focus, -fieldset[disabled] .btn-primary:active, -fieldset[disabled] .btn-primary:focus, -fieldset[disabled] .btn-primary:hover { - background-color: #337ab7; - border-color: #2e6da4 -} - -.btn-primary .badge { - color: #337ab7; - background-color: #fff -} - -.btn-success { - color: #fff; - background-color: #5cb85c; - border-color: #4cae4c -} - -.btn-success.active, -.btn-success.focus, -.btn-success:active, -.btn-success:focus, -.btn-success:hover, -.open>.dropdown-toggle.btn-success { - color: #fff; - background-color: #449d44; - border-color: #398439 -} - -.btn-success.active, -.btn-success:active, -.open>.dropdown-toggle.btn-success { - background-image: none -} - -.btn-success.disabled, -.btn-success.disabled.active, -.btn-success.disabled.focus, -.btn-success.disabled:active, -.btn-success.disabled:focus, -.btn-success.disabled:hover, -.btn-success[disabled], -.btn-success[disabled].active, -.btn-success[disabled].focus, -.btn-success[disabled]:active, -.btn-success[disabled]:focus, -.btn-success[disabled]:hover, -fieldset[disabled] .btn-success, -fieldset[disabled] .btn-success.active, -fieldset[disabled] .btn-success.focus, -fieldset[disabled] .btn-success:active, -fieldset[disabled] .btn-success:focus, -fieldset[disabled] .btn-success:hover { - background-color: #5cb85c; - border-color: #4cae4c -} - -.btn-success .badge { - color: #5cb85c; - background-color: #fff -} - -.btn-info { - color: #fff; - background-color: #5bc0de; - border-color: #46b8da -} - -.btn-info.active, -.btn-info.focus, -.btn-info:active, -.btn-info:focus, -.btn-info:hover, -.open>.dropdown-toggle.btn-info { - color: #fff; - background-color: #31b0d5; - border-color: #269abc -} - -.btn-info.active, -.btn-info:active, -.open>.dropdown-toggle.btn-info { - background-image: none -} - -.btn-info.disabled, -.btn-info.disabled.active, -.btn-info.disabled.focus, -.btn-info.disabled:active, -.btn-info.disabled:focus, -.btn-info.disabled:hover, -.btn-info[disabled], -.btn-info[disabled].active, -.btn-info[disabled].focus, -.btn-info[disabled]:active, -.btn-info[disabled]:focus, -.btn-info[disabled]:hover, -fieldset[disabled] .btn-info, -fieldset[disabled] .btn-info.active, -fieldset[disabled] .btn-info.focus, -fieldset[disabled] .btn-info:active, -fieldset[disabled] .btn-info:focus, -fieldset[disabled] .btn-info:hover { - background-color: #5bc0de; - border-color: #46b8da -} - -.btn-info .badge { - color: #5bc0de; - background-color: #fff -} - -.btn-warning { - color: #fff; - background-color: #f0ad4e; - border-color: #eea236 -} - -.btn-warning.active, -.btn-warning.focus, -.btn-warning:active, -.btn-warning:focus, -.btn-warning:hover, -.open>.dropdown-toggle.btn-warning { - color: #fff; - background-color: #ec971f; - border-color: #d58512 -} - -.btn-warning.active, -.btn-warning:active, -.open>.dropdown-toggle.btn-warning { - background-image: none -} - -.btn-warning.disabled, -.btn-warning.disabled.active, -.btn-warning.disabled.focus, -.btn-warning.disabled:active, -.btn-warning.disabled:focus, -.btn-warning.disabled:hover, -.btn-warning[disabled], -.btn-warning[disabled].active, -.btn-warning[disabled].focus, -.btn-warning[disabled]:active, -.btn-warning[disabled]:focus, -.btn-warning[disabled]:hover, -fieldset[disabled] .btn-warning, -fieldset[disabled] .btn-warning.active, -fieldset[disabled] .btn-warning.focus, -fieldset[disabled] .btn-warning:active, -fieldset[disabled] .btn-warning:focus, -fieldset[disabled] .btn-warning:hover { - background-color: #f0ad4e; - border-color: #eea236 -} - -.btn-warning .badge { - color: #f0ad4e; - background-color: #fff -} - -.btn-danger { - color: #fff; - background-color: #d9534f; - border-color: #d43f3a -} - -.btn-danger.active, -.btn-danger.focus, -.btn-danger:active, -.btn-danger:focus, -.btn-danger:hover, -.open>.dropdown-toggle.btn-danger { - color: #fff; - background-color: #c9302c; - border-color: #ac2925 -} - -.btn-danger.active, -.btn-danger:active, -.open>.dropdown-toggle.btn-danger { - background-image: none -} - -.btn-danger.disabled, -.btn-danger.disabled.active, -.btn-danger.disabled.focus, -.btn-danger.disabled:active, -.btn-danger.disabled:focus, -.btn-danger.disabled:hover, -.btn-danger[disabled], -.btn-danger[disabled].active, -.btn-danger[disabled].focus, -.btn-danger[disabled]:active, -.btn-danger[disabled]:focus, -.btn-danger[disabled]:hover, -fieldset[disabled] .btn-danger, -fieldset[disabled] .btn-danger.active, -fieldset[disabled] .btn-danger.focus, -fieldset[disabled] .btn-danger:active, -fieldset[disabled] .btn-danger:focus, -fieldset[disabled] .btn-danger:hover { - background-color: #d9534f; - border-color: #d43f3a -} - -.btn-danger .badge { - color: #d9534f; - background-color: #fff -} - -.btn-link { - font-weight: 400; - color: #337ab7; - border-radius: 0 -} - -.btn-link, -.btn-link.active, -.btn-link:active, -.btn-link[disabled], -fieldset[disabled] .btn-link { - background-color: transparent; -} - -.btn-link, -.btn-link:active, -.btn-link:focus, -.btn-link:hover { - border-color: transparent -} - -.btn-link:focus, -.btn-link:hover { - color: #23527c; - text-decoration: underline; - background-color: transparent -} - -.btn-link[disabled]:focus, -.btn-link[disabled]:hover, -fieldset[disabled] .btn-link:focus, -fieldset[disabled] .btn-link:hover { - color: #777; - text-decoration: none -} - -.btn-group-lg>.btn, -.btn-lg { - padding: 10px 16px; - font-size: 18px; - line-height: 1.3333333; - border-radius: 6px -} - -.btn-group-sm>.btn, -.btn-sm { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px -} - -.btn-group-xs>.btn, -.btn-xs { - padding: 1px 5px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px -} - -.btn-block { - display: block; - width: 100% -} - -.btn-block+.btn-block { - margin-top: 5px -} - -input[type=button].btn-block, -input[type=reset].btn-block, -input[type=submit].btn-block { - width: 100% -} - -.fade { - opacity: 0; - -webkit-transition: opacity .15s linear; - -o-transition: opacity .15s linear; - transition: opacity .15s linear -} - -.fade.in { - opacity: 1 -} - -.collapse { - display: none; - visibility: hidden -} - -.collapse.in { - display: block; - visibility: visible -} - -tr.collapse.in { - display: table-row -} - -tbody.collapse.in { - display: table-row-group -} - -.collapsing { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition-timing-function: ease; - -o-transition-timing-function: ease; - transition-timing-function: ease; - -webkit-transition-duration: .35s; - -o-transition-duration: .35s; - transition-duration: .35s; - -webkit-transition-property: height, visibility; - -o-transition-property: height, visibility; - transition-property: height, visibility -} - -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: 4px solid; - border-right: 4px solid transparent; - border-left: 4px solid transparent -} - -.dropdown, -.dropup { - position: relative -} - -.dropdown-toggle:focus { - outline: 0 -} - -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - font-size: 14px; - text-align: left; - list-style: none; - background-color: #fff; - -webkit-background-clip: padding-box; - background-clip: padding-box; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, .15); - border-radius: 4px; -} - -.dropdown-menu.pull-right { - right: 0; - left: auto -} - -.dropdown-menu .divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5 -} - -.dropdown-menu>li>a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: 400; - line-height: 1.42857143; - color: #333; - white-space: nowrap -} - -.dropdown-menu>li>a:focus, -.dropdown-menu>li>a:hover { - color: #262626; - text-decoration: none; - background-color: #f5f5f5 -} - -.dropdown-menu>.active>a, -.dropdown-menu>.active>a:focus, -.dropdown-menu>.active>a:hover { - color: #fff; - text-decoration: none; - background-color: #337ab7; - outline: 0 -} - -.dropdown-menu>.disabled>a, -.dropdown-menu>.disabled>a:focus, -.dropdown-menu>.disabled>a:hover { - color: #777 -} - -.dropdown-menu>.disabled>a:focus, -.dropdown-menu>.disabled>a:hover { - text-decoration: none; - cursor: not-allowed; - background-color: transparent; - background-image: none; - filter: progid: DXImageTransform.Microsoft.gradient(enabled=false) -} - -.open>.dropdown-menu { - display: block -} - -.open>a { - outline: 0 -} - -.dropdown-menu-right { - right: 0; - left: auto -} - -.dropdown-menu-left { - right: auto; - left: 0 -} - -.dropdown-header { - display: block; - padding: 3px 20px; - font-size: 12px; - line-height: 1.42857143; - color: #777; - white-space: nowrap -} - -.dropdown-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 990 -} - -.pull-right>.dropdown-menu { - right: 0; - left: auto -} - -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - content: ""; - border-top: 0; - border-bottom: 4px solid -} - -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 2px -} - -@media (min-width:768px) { - .navbar-right .dropdown-menu { - right: 0; - left: auto - } - .navbar-right .dropdown-menu-left { - right: auto; - left: 0 - } -} - -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-block; - vertical-align: middle -} - -.btn-group-vertical>.btn, -.btn-group>.btn { - position: relative; - float: left -} - -.btn-group-vertical>.btn.active, -.btn-group-vertical>.btn:active, -.btn-group-vertical>.btn:focus, -.btn-group-vertical>.btn:hover, -.btn-group>.btn.active, -.btn-group>.btn:active, -.btn-group>.btn:focus, -.btn-group>.btn:hover { - z-index: 2 -} - -.btn-group .btn+.btn, -.btn-group .btn+.btn-group, -.btn-group .btn-group+.btn, -.btn-group .btn-group+.btn-group { - margin-left: -1px -} - -.btn-toolbar { - margin-left: -5px -} - -.btn-toolbar .btn-group, -.btn-toolbar .input-group { - float: left -} - -.btn-toolbar>.btn, -.btn-toolbar>.btn-group, -.btn-toolbar>.input-group { - margin-left: 5px -} - -.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { - border-radius: 0 -} - -.btn-group>.btn:first-child { - margin-left: 0 -} - -.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle) { - border-top-right-radius: 0; - border-bottom-right-radius: 0 -} - -.btn-group>.btn:last-child:not(:first-child), -.btn-group>.dropdown-toggle:not(:first-child) { - border-top-left-radius: 0; - border-bottom-left-radius: 0 -} - -.btn-group>.btn-group { - float: left -} - -.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn { - border-radius: 0 -} - -.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child, -.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle { - border-top-right-radius: 0; - border-bottom-right-radius: 0 -} - -.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child { - border-top-left-radius: 0; - border-bottom-left-radius: 0 -} - -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0 -} - -.btn-group>.btn+.dropdown-toggle { - padding-right: 8px; - padding-left: 8px -} - -.btn-group>.btn-lg+.dropdown-toggle { - padding-right: 12px; - padding-left: 12px -} - -.btn-group.open .dropdown-toggle { -} - -.btn-group.open .dropdown-toggle.btn-link { -} - -.btn .caret { - margin-left: 0 -} - -.btn-lg .caret { - border-width: 5px 5px 0; - border-bottom-width: 0 -} - -.dropup .btn-lg .caret { - border-width: 0 5px 5px -} - -.btn-group-vertical>.btn, -.btn-group-vertical>.btn-group, -.btn-group-vertical>.btn-group>.btn { - display: block; - float: none; - width: 100%; - max-width: 100% -} - -.btn-group-vertical>.btn-group>.btn { - float: none -} - -.btn-group-vertical>.btn+.btn, -.btn-group-vertical>.btn+.btn-group, -.btn-group-vertical>.btn-group+.btn, -.btn-group-vertical>.btn-group+.btn-group { - margin-top: -1px; - margin-left: 0 -} - -.btn-group-vertical>.btn:not(:first-child):not(:last-child) { - border-radius: 0 -} - -.btn-group-vertical>.btn:first-child:not(:last-child) { - border-top-right-radius: 4px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0 -} - -.btn-group-vertical>.btn:last-child:not(:first-child) { - border-top-left-radius: 0; - border-top-right-radius: 0; - border-bottom-left-radius: 4px -} - -.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn { - border-radius: 0 -} - -.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child, -.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0 -} - -.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child { - border-top-left-radius: 0; - border-top-right-radius: 0 -} - -.btn-group-justified { - display: table; - width: 100%; - table-layout: fixed; - border-collapse: separate -} - -.btn-group-justified>.btn, -.btn-group-justified>.btn-group { - display: table-cell; - float: none; - width: 1% -} - -.btn-group-justified>.btn-group .btn { - width: 100% -} - -.btn-group-justified>.btn-group .dropdown-menu { - left: auto -} - -[data-toggle=buttons]>.btn input[type=checkbox], -[data-toggle=buttons]>.btn input[type=radio], -[data-toggle=buttons]>.btn-group>.btn input[type=checkbox], -[data-toggle=buttons]>.btn-group>.btn input[type=radio] { - position: absolute; - clip: rect(0, 0, 0, 0); -} - -.input-group { - position: relative; - display: table; - border-collapse: separate -} - -.input-group[class*=col-] { - float: none; - padding-right: 0; - padding-left: 0 -} - -.input-group .form-control { - position: relative; - z-index: 2; - float: left; - width: 100%; - margin-bottom: 0 -} - -.input-group-lg>.form-control, -.input-group-lg>.input-group-addon, -.input-group-lg>.input-group-btn>.btn { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.3333333; - border-radius: 6px -} - -select.input-group-lg>.form-control, -select.input-group-lg>.input-group-addon, -select.input-group-lg>.input-group-btn>.btn { - height: 46px; - line-height: 46px -} - -select[multiple].input-group-lg>.form-control, -select[multiple].input-group-lg>.input-group-addon, -select[multiple].input-group-lg>.input-group-btn>.btn, -textarea.input-group-lg>.form-control, -textarea.input-group-lg>.input-group-addon, -textarea.input-group-lg>.input-group-btn>.btn { - height: auto -} - -.input-group-sm>.form-control, -.input-group-sm>.input-group-addon, -.input-group-sm>.input-group-btn>.btn { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px -} - -select.input-group-sm>.form-control, -select.input-group-sm>.input-group-addon, -select.input-group-sm>.input-group-btn>.btn { - height: 30px; - line-height: 30px -} - -select[multiple].input-group-sm>.form-control, -select[multiple].input-group-sm>.input-group-addon, -select[multiple].input-group-sm>.input-group-btn>.btn, -textarea.input-group-sm>.form-control, -textarea.input-group-sm>.input-group-addon, -textarea.input-group-sm>.input-group-btn>.btn { - height: auto -} - -.input-group .form-control, -.input-group-addon, -.input-group-btn { - display: table-cell -} - -.input-group .form-control:not(:first-child):not(:last-child), -.input-group-addon:not(:first-child):not(:last-child), -.input-group-btn:not(:first-child):not(:last-child) { - border-radius: 0 -} - -.input-group-addon, -.input-group-btn { - width: 1%; - white-space: nowrap; - vertical-align: middle -} - -.input-group-addon { - padding: 6px 12px; - font-size: 14px; - font-weight: 400; - line-height: 1; - color: #555; - text-align: center; - background-color: #eee; - border: 1px solid #ccc; - border-radius: 4px -} - -.input-group-addon.input-sm { - padding: 5px 10px; - font-size: 12px; - border-radius: 3px -} - -.input-group-addon.input-lg { - padding: 10px 16px; - font-size: 18px; - border-radius: 6px -} - -.input-group-addon input[type=checkbox], -.input-group-addon input[type=radio] { - margin-top: 0 -} - -.input-group .form-control:first-child, -.input-group-addon:first-child, -.input-group-btn:first-child>.btn, -.input-group-btn:first-child>.btn-group>.btn, -.input-group-btn:first-child>.dropdown-toggle, -.input-group-btn:last-child>.btn-group:not(:last-child)>.btn, -.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle) { - border-top-right-radius: 0; - border-bottom-right-radius: 0 -} - -.input-group-addon:first-child { - border-right: 0 -} - -.input-group .form-control:last-child, -.input-group-addon:last-child, -.input-group-btn:first-child>.btn-group:not(:first-child)>.btn, -.input-group-btn:first-child>.btn:not(:first-child), -.input-group-btn:last-child>.btn, -.input-group-btn:last-child>.btn-group>.btn, -.input-group-btn:last-child>.dropdown-toggle { - border-top-left-radius: 0; - border-bottom-left-radius: 0 -} - -.input-group-addon:last-child { - border-left: 0 -} - -.input-group-btn { - position: relative; - font-size: 0; - white-space: nowrap -} - -.input-group-btn>.btn { - position: relative -} - -.input-group-btn>.btn+.btn { - margin-left: -1px -} - -.input-group-btn>.btn:active, -.input-group-btn>.btn:focus, -.input-group-btn>.btn:hover { - z-index: 2 -} - -.input-group-btn:first-child>.btn, -.input-group-btn:first-child>.btn-group { - margin-right: -1px -} - -.input-group-btn:last-child>.btn, -.input-group-btn:last-child>.btn-group { - margin-left: -1px -} - -.nav { - padding-left: 0; - margin-bottom: 0; - list-style: none -} - -.nav>li { - position: relative; - display: block -} - -.nav>li>a { - position: relative; - display: block; - padding: 10px 15px -} - -.nav>li>a:focus, -.nav>li>a:hover { - text-decoration: none; - background-color: #eee -} - -.nav>li.disabled>a { - color: #777 -} - -.nav>li.disabled>a:focus, -.nav>li.disabled>a:hover { - color: #777; - text-decoration: none; - cursor: not-allowed; - background-color: transparent -} - -.nav .open>a, -.nav .open>a:focus, -.nav .open>a:hover { - background-color: #eee; - border-color: #337ab7 -} - -.nav .nav-divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5 -} - -.nav>li>a>img { - max-width: none -} - -.nav-tabs { - border-bottom: 1px solid #ddd -} - -.nav-tabs>li { - float: left; - margin-bottom: -1px -} - -.nav-tabs>li>a { - margin-right: 2px; - line-height: 1.42857143; - border: 1px solid transparent; - border-radius: 4px 4px 0 0 -} - -.nav-tabs>li>a:hover { - border-color: #eee #eee #ddd -} - -.nav-tabs>li.active>a, -.nav-tabs>li.active>a:focus, -.nav-tabs>li.active>a:hover { - color: #555; - cursor: default; - background-color: #fff; - border: 1px solid #ddd; - border-bottom-color: transparent -} - -.nav-tabs.nav-justified { - width: 100%; - border-bottom: 0 -} - -.nav-tabs.nav-justified>li { - float: none -} - -.nav-tabs.nav-justified>li>a { - margin-bottom: 5px; - text-align: center -} - -.nav-tabs.nav-justified>.dropdown .dropdown-menu { - top: auto; - left: auto -} - -@media (min-width:768px) { - .nav-tabs.nav-justified>li { - display: table-cell; - width: 1% - } - .nav-tabs.nav-justified>li>a { - margin-bottom: 0 - } -} - -.nav-tabs.nav-justified>li>a { - margin-right: 0; - border-radius: 4px -} - -.nav-tabs.nav-justified>.active>a, -.nav-tabs.nav-justified>.active>a:focus, -.nav-tabs.nav-justified>.active>a:hover { - border: 1px solid #ddd -} - -@media (min-width:768px) { - .nav-tabs.nav-justified>li>a { - border-bottom: 1px solid #ddd; - border-radius: 4px 4px 0 0 - } - .nav-tabs.nav-justified>.active>a, - .nav-tabs.nav-justified>.active>a:focus, - .nav-tabs.nav-justified>.active>a:hover { - border-bottom-color: #fff - } -} - -.nav-pills>li { - float: left -} - -.nav-pills>li>a { - border-radius: 4px -} - -.nav-pills>li+li { - margin-left: 2px -} - -.nav-pills>li.active>a, -.nav-pills>li.active>a:focus, -.nav-pills>li.active>a:hover { - color: #fff; - background-color: #337ab7 -} - -.nav-stacked>li { - float: none -} - -.nav-stacked>li+li { - margin-top: 2px; - margin-left: 0 -} - -.nav-justified { - width: 100% -} - -.nav-justified>li { - float: none -} - -.nav-justified>li>a { - margin-bottom: 5px; - text-align: center -} - -.nav-justified>.dropdown .dropdown-menu { - top: auto; - left: auto -} - -@media (min-width:768px) { - .nav-justified>li { - display: table-cell; - width: 1% - } - .nav-justified>li>a { - margin-bottom: 0 - } -} - -.nav-tabs-justified { - border-bottom: 0 -} - -.nav-tabs-justified>li>a { - margin-right: 0; - border-radius: 4px -} - -.nav-tabs-justified>.active>a, -.nav-tabs-justified>.active>a:focus, -.nav-tabs-justified>.active>a:hover { - border: 1px solid #ddd -} - -@media (min-width:768px) { - .nav-tabs-justified>li>a { - border-bottom: 1px solid #ddd; - border-radius: 4px 4px 0 0 - } - .nav-tabs-justified>.active>a, - .nav-tabs-justified>.active>a:focus, - .nav-tabs-justified>.active>a:hover { - border-bottom-color: #fff - } -} - -.tab-content>.tab-pane { - display: none; - visibility: hidden -} - -.tab-content>.active { - display: block; - visibility: visible -} - -.nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-left-radius: 0; - border-top-right-radius: 0 -} - -.navbar { - position: relative; - min-height: 50px; - margin-bottom: 20px; - border: 1px solid transparent -} - -@media (min-width:768px) { - .navbar { - border-radius: 4px - } -} - -@media (min-width:768px) { - .navbar-header { - float: left - } -} - -.navbar-collapse { - padding-right: 15px; - padding-left: 15px; - overflow-x: visible; - -webkit-overflow-scrolling: touch; - border-top: 1px solid transparent; -} - -.navbar-collapse.in { - overflow-y: auto -} - -@media (min-width:768px) { - .navbar-collapse { - width: auto; - border-top: 0; - } - .navbar-collapse.collapse { - display: block!important; - height: auto!important; - padding-bottom: 0; - overflow: visible!important; - visibility: visible!important - } - .navbar-collapse.in { - overflow-y: visible - } - .navbar-fixed-bottom .navbar-collapse, - .navbar-fixed-top .navbar-collapse, - .navbar-static-top .navbar-collapse { - padding-right: 0; - padding-left: 0 - } -} - -.navbar-fixed-bottom .navbar-collapse, -.navbar-fixed-top .navbar-collapse { - max-height: 340px -} - -@media (max-device-width:480px) and (orientation:landscape) { - .navbar-fixed-bottom .navbar-collapse, - .navbar-fixed-top .navbar-collapse { - max-height: 200px - } -} - -.container-fluid>.navbar-collapse, -.container-fluid>.navbar-header, -.container>.navbar-collapse, -.container>.navbar-header { - margin-right: -15px; - margin-left: -15px -} - -@media (min-width:768px) { - .container-fluid>.navbar-collapse, - .container-fluid>.navbar-header, - .container>.navbar-collapse, - .container>.navbar-header { - margin-right: 0; - margin-left: 0 - } -} - -.navbar-static-top { - z-index: 1000; - border-width: 0 0 1px -} - -@media (min-width:768px) { - .navbar-static-top { - border-radius: 0 - } -} - -.navbar-fixed-bottom, -.navbar-fixed-top { - position: fixed; - right: 0; - left: 0; - z-index: 1030 -} - -@media (min-width:768px) { - .navbar-fixed-bottom, - .navbar-fixed-top { - border-radius: 0 - } -} - -.navbar-fixed-top { - top: 0; - border-width: 0 0 1px -} - -.navbar-fixed-bottom { - bottom: 0; - margin-bottom: 0; - border-width: 1px 0 0 -} - -.navbar-brand { - float: left; - height: 50px; - padding: 15px 15px; - font-size: 18px; - line-height: 20px -} - -.navbar-brand:focus, -.navbar-brand:hover { - text-decoration: none -} - -.navbar-brand>img { - display: block -} - -@media (min-width:768px) { - .navbar>.container .navbar-brand, - .navbar>.container-fluid .navbar-brand { - margin-left: -15px - } -} - -.navbar-toggle { - position: relative; - float: right; - padding: 9px 10px; - margin-top: 8px; - margin-right: 15px; - margin-bottom: 8px; - background-color: transparent; - background-image: none; - border: 1px solid transparent; - border-radius: 4px -} - -.navbar-toggle:focus { - outline: 0 -} - -.navbar-toggle .icon-bar { - display: block; - width: 22px; - height: 2px; - border-radius: 1px -} - -.navbar-toggle .icon-bar+.icon-bar { - margin-top: 4px -} - -@media (min-width:768px) { - .navbar-toggle { - display: none - } -} - -.navbar-nav { - margin: 7.5px -15px -} - -.navbar-nav>li>a { - padding-top: 10px; - padding-bottom: 10px; - line-height: 20px -} - -@media (max-width:767px) { - .navbar-nav .open .dropdown-menu { - position: static; - float: none; - width: auto; - margin-top: 0; - background-color: transparent; - border: 0; - } - .navbar-nav .open .dropdown-menu .dropdown-header, - .navbar-nav .open .dropdown-menu>li>a { - padding: 5px 15px 5px 25px - } - .navbar-nav .open .dropdown-menu>li>a { - line-height: 20px - } - .navbar-nav .open .dropdown-menu>li>a:focus, - .navbar-nav .open .dropdown-menu>li>a:hover { - background-image: none - } -} - -@media (min-width:768px) { - .navbar-nav { - float: left; - margin: 0 - } - .navbar-nav>li { - float: left - } - .navbar-nav>li>a { - padding-top: 15px; - padding-bottom: 15px - } -} - -.navbar-form { - padding: 10px 15px; - margin-top: 8px; - margin-right: -15px; - margin-bottom: 8px; - margin-left: -15px; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; -} - -@media (min-width:768px) { - .navbar-form .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle - } - .navbar-form .form-control { - display: inline-block; - width: auto; - vertical-align: middle - } - .navbar-form .form-control-static { - display: inline-block - } - .navbar-form .input-group { - display: inline-table; - vertical-align: middle - } - .navbar-form .input-group .form-control, - .navbar-form .input-group .input-group-addon, - .navbar-form .input-group .input-group-btn { - width: auto - } - .navbar-form .input-group>.form-control { - width: 100% - } - .navbar-form .control-label { - margin-bottom: 0; - vertical-align: middle - } - .navbar-form .checkbox, - .navbar-form .radio { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - vertical-align: middle - } - .navbar-form .checkbox label, - .navbar-form .radio label { - padding-left: 0 - } - .navbar-form .checkbox input[type=checkbox], - .navbar-form .radio input[type=radio] { - position: relative; - margin-left: 0 - } - .navbar-form .has-feedback .form-control-feedback { - top: 0 - } -} - -@media (max-width:767px) { - .navbar-form .form-group { - margin-bottom: 5px - } - .navbar-form .form-group:last-child { - margin-bottom: 0 - } -} - -@media (min-width:768px) { - .navbar-form { - width: auto; - padding-top: 0; - padding-bottom: 0; - margin-right: 0; - margin-left: 0; - border: 0; - } -} - -.navbar-nav>li>.dropdown-menu { - margin-top: 0; - border-top-left-radius: 0; - border-top-right-radius: 0 -} - -.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu { - margin-bottom: 0; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0 -} - -.navbar-btn { - margin-top: 8px; - margin-bottom: 8px -} - -.navbar-btn.btn-sm { - margin-top: 10px; - margin-bottom: 10px -} - -.navbar-btn.btn-xs { - margin-top: 14px; - margin-bottom: 14px -} - -.navbar-text { - margin-top: 15px; - margin-bottom: 15px -} - -@media (min-width:768px) { - .navbar-text { - float: left; - margin-right: 15px; - margin-left: 15px - } -} - -@media (min-width:768px) { - .navbar-left { - float: left!important - } - .navbar-right { - float: right!important; - margin-right: -15px - } - .navbar-right~.navbar-right { - margin-right: 0 - } -} - -.navbar-default { - background-color: #f8f8f8; - border-color: #e7e7e7 -} - -.navbar-default .navbar-brand { - color: #777 -} - -.navbar-default .navbar-brand:focus, -.navbar-default .navbar-brand:hover { - color: #5e5e5e; - background-color: transparent -} - -.navbar-default .navbar-text { - color: #777 -} - -.navbar-default .navbar-nav>li>a { - color: #777 -} - -.navbar-default .navbar-nav>li>a:focus, -.navbar-default .navbar-nav>li>a:hover { - color: #333; - background-color: transparent -} - -.navbar-default .navbar-nav>.active>a, -.navbar-default .navbar-nav>.active>a:focus, -.navbar-default .navbar-nav>.active>a:hover { - color: #555; - background-color: #e7e7e7 -} - -.navbar-default .navbar-nav>.disabled>a, -.navbar-default .navbar-nav>.disabled>a:focus, -.navbar-default .navbar-nav>.disabled>a:hover { - color: #ccc; - background-color: transparent -} - -.navbar-default .navbar-toggle { - border-color: #ddd -} - -.navbar-default .navbar-toggle:focus, -.navbar-default .navbar-toggle:hover { - background-color: #ddd -} - -.navbar-default .navbar-toggle .icon-bar { - background-color: #888 -} - -.navbar-default .navbar-collapse, -.navbar-default .navbar-form { - border-color: #e7e7e7 -} - -.navbar-default .navbar-nav>.open>a, -.navbar-default .navbar-nav>.open>a:focus, -.navbar-default .navbar-nav>.open>a:hover { - color: #555; - background-color: #e7e7e7 -} - -@media (max-width:767px) { - .navbar-default .navbar-nav .open .dropdown-menu>li>a { - color: #777 - } - .navbar-default .navbar-nav .open .dropdown-menu>li>a:focus, - .navbar-default .navbar-nav .open .dropdown-menu>li>a:hover { - color: #333; - background-color: transparent - } - .navbar-default .navbar-nav .open .dropdown-menu>.active>a, - .navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus, - .navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover { - color: #555; - background-color: #e7e7e7 - } - .navbar-default .navbar-nav .open .dropdown-menu>.disabled>a, - .navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus, - .navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover { - color: #ccc; - background-color: transparent - } -} - -.navbar-default .navbar-link { - color: #777 -} - -.navbar-default .navbar-link:hover { - color: #333 -} - -.navbar-default .btn-link { - color: #777 -} - -.navbar-default .btn-link:focus, -.navbar-default .btn-link:hover { - color: #333 -} - -.navbar-default .btn-link[disabled]:focus, -.navbar-default .btn-link[disabled]:hover, -fieldset[disabled] .navbar-default .btn-link:focus, -fieldset[disabled] .navbar-default .btn-link:hover { - color: #ccc -} - -.navbar-inverse { - background-color: #222; - border-color: #080808 -} - -.navbar-inverse .navbar-brand { - color: #9d9d9d -} - -.navbar-inverse .navbar-brand:focus, -.navbar-inverse .navbar-brand:hover { - color: #fff; - background-color: transparent -} - -.navbar-inverse .navbar-text { - color: #9d9d9d -} - -.navbar-inverse .navbar-nav>li>a { - color: #9d9d9d -} - -.navbar-inverse .navbar-nav>li>a:focus, -.navbar-inverse .navbar-nav>li>a:hover { - color: #fff; - background-color: transparent -} - -.navbar-inverse .navbar-nav>.active>a, -.navbar-inverse .navbar-nav>.active>a:focus, -.navbar-inverse .navbar-nav>.active>a:hover { - color: #fff; - background-color: #080808 -} - -.navbar-inverse .navbar-nav>.disabled>a, -.navbar-inverse .navbar-nav>.disabled>a:focus, -.navbar-inverse .navbar-nav>.disabled>a:hover { - color: #444; - background-color: transparent -} - -.navbar-inverse .navbar-toggle { - border-color: #333 -} - -.navbar-inverse .navbar-toggle:focus, -.navbar-inverse .navbar-toggle:hover { - background-color: #333 -} - -.navbar-inverse .navbar-toggle .icon-bar { - background-color: #fff -} - -.navbar-inverse .navbar-collapse, -.navbar-inverse .navbar-form { - border-color: #101010 -} - -.navbar-inverse .navbar-nav>.open>a, -.navbar-inverse .navbar-nav>.open>a:focus, -.navbar-inverse .navbar-nav>.open>a:hover { - color: #fff; - background-color: #080808 -} - -@media (max-width:767px) { - .navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header { - border-color: #080808 - } - .navbar-inverse .navbar-nav .open .dropdown-menu .divider { - background-color: #080808 - } - .navbar-inverse .navbar-nav .open .dropdown-menu>li>a { - color: #9d9d9d - } - .navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus, - .navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover { - color: #fff; - background-color: transparent - } - .navbar-inverse .navbar-nav .open .dropdown-menu>.active>a, - .navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus, - .navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover { - color: #fff; - background-color: #080808 - } - .navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a, - .navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus, - .navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover { - color: #444; - background-color: transparent - } -} - -.navbar-inverse .navbar-link { - color: #9d9d9d -} - -.navbar-inverse .navbar-link:hover { - color: #fff -} - -.navbar-inverse .btn-link { - color: #9d9d9d -} - -.navbar-inverse .btn-link:focus, -.navbar-inverse .btn-link:hover { - color: #fff -} - -.navbar-inverse .btn-link[disabled]:focus, -.navbar-inverse .btn-link[disabled]:hover, -fieldset[disabled] .navbar-inverse .btn-link:focus, -fieldset[disabled] .navbar-inverse .btn-link:hover { - color: #444 -} - -.breadcrumb { - padding: 8px 15px; - margin-bottom: 20px; - list-style: none; - background-color: #f5f5f5; - border-radius: 4px -} - -.breadcrumb>li { - display: inline-block -} - -.breadcrumb>li+li:before { - padding: 0 5px; - color: #ccc; - content: "/\00a0" -} - -.breadcrumb>.active { - color: #777 -} - -.pagination { - display: inline-block; - padding-left: 0; - margin: 20px 0; - border-radius: 4px -} - -.pagination>li { - display: inline -} - -.pagination>li>a, -.pagination>li>span { - position: relative; - float: left; - padding: 6px 12px; - margin-left: -1px; - line-height: 1.42857143; - color: #337ab7; - text-decoration: none; - background-color: #fff; - border: 1px solid #ddd -} - -.pagination>li:first-child>a, -.pagination>li:first-child>span { - margin-left: 0; - border-top-left-radius: 4px; - border-bottom-left-radius: 4px -} - -.pagination>li:last-child>a, -.pagination>li:last-child>span { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px -} - -.pagination>li>a:focus, -.pagination>li>a:hover, -.pagination>li>span:focus, -.pagination>li>span:hover { - color: #23527c; - background-color: #eee; - border-color: #ddd -} - -.pagination>.active>a, -.pagination>.active>a:focus, -.pagination>.active>a:hover, -.pagination>.active>span, -.pagination>.active>span:focus, -.pagination>.active>span:hover { - z-index: 2; - color: #fff; - cursor: default; - background-color: #337ab7; - border-color: #337ab7 -} - -.pagination>.disabled>a, -.pagination>.disabled>a:focus, -.pagination>.disabled>a:hover, -.pagination>.disabled>span, -.pagination>.disabled>span:focus, -.pagination>.disabled>span:hover { - color: #777; - cursor: not-allowed; - background-color: #fff; - border-color: #ddd -} - -.pagination-lg>li>a, -.pagination-lg>li>span { - padding: 10px 16px; - font-size: 18px -} - -.pagination-lg>li:first-child>a, -.pagination-lg>li:first-child>span { - border-top-left-radius: 6px; - border-bottom-left-radius: 6px -} - -.pagination-lg>li:last-child>a, -.pagination-lg>li:last-child>span { - border-top-right-radius: 6px; - border-bottom-right-radius: 6px -} - -.pagination-sm>li>a, -.pagination-sm>li>span { - padding: 5px 10px; - font-size: 12px -} - -.pagination-sm>li:first-child>a, -.pagination-sm>li:first-child>span { - border-top-left-radius: 3px; - border-bottom-left-radius: 3px -} - -.pagination-sm>li:last-child>a, -.pagination-sm>li:last-child>span { - border-top-right-radius: 3px; - border-bottom-right-radius: 3px -} - -.pager { - padding-left: 0; - margin: 20px 0; - text-align: center; - list-style: none -} - -.pager li { - display: inline -} - -.pager li>a, -.pager li>span { - display: inline-block; - padding: 5px 14px; - background-color: #fff; - border: 1px solid #ddd; - border-radius: 15px -} - -.pager li>a:focus, -.pager li>a:hover { - text-decoration: none; - background-color: #eee -} - -.pager .next>a, -.pager .next>span { - float: right -} - -.pager .previous>a, -.pager .previous>span { - float: left -} - -.pager .disabled>a, -.pager .disabled>a:focus, -.pager .disabled>a:hover, -.pager .disabled>span { - color: #777; - cursor: not-allowed; - background-color: #fff -} - -.label { - display: inline; - padding: .2em .6em .3em; - font-size: 75%; - font-weight: 700; - line-height: 1; - color: #fff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: .25em -} - -a.label:focus, -a.label:hover { - color: #fff; - text-decoration: none; - cursor: pointer -} - -.label:empty { - display: none -} - -.btn .label { - position: relative; - top: -1px -} - -.label-default { - background-color: #777 -} - -.label-default[href]:focus, -.label-default[href]:hover { - background-color: #5e5e5e -} - -.label-primary { - background-color: #337ab7 -} - -.label-primary[href]:focus, -.label-primary[href]:hover { - background-color: #286090 -} - -.label-success { - background-color: #5cb85c -} - -.label-success[href]:focus, -.label-success[href]:hover { - background-color: #449d44 -} - -.label-info { - background-color: #5bc0de -} - -.label-info[href]:focus, -.label-info[href]:hover { - background-color: #31b0d5 -} - -.label-warning { - background-color: #f0ad4e -} - -.label-warning[href]:focus, -.label-warning[href]:hover { - background-color: #ec971f -} - -.label-danger { - background-color: #d9534f -} - -.label-danger[href]:focus, -.label-danger[href]:hover { - background-color: #c9302c -} - -.badge { - display: inline-block; - min-width: 10px; - padding: 3px 7px; - font-size: 12px; - font-weight: 700; - line-height: 1; - color: #fff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - background-color: #777; - border-radius: 10px -} - -.badge:empty { - display: none -} - -.btn .badge { - position: relative; - top: -1px -} - -.btn-xs .badge { - top: 0; - padding: 1px 5px -} - -a.badge:focus, -a.badge:hover { - color: #fff; - text-decoration: none; - cursor: pointer -} - -.list-group-item.active>.badge, -.nav-pills>.active>a>.badge { - color: #337ab7; - background-color: #fff -} - -.list-group-item>.badge { - float: right -} - -.list-group-item>.badge+.badge { - margin-right: 5px -} - -.nav-pills>li>a>.badge { - margin-left: 3px -} - -.jumbotron { - padding: 30px 15px; - margin-bottom: 30px; - color: inherit; - background-color: #eee -} - -.jumbotron .h1, -.jumbotron h1 { - color: inherit -} - -.jumbotron p { - margin-bottom: 15px; - font-size: 21px; - font-weight: 200 -} - -.jumbotron>hr { - border-top-color: #d5d5d5 -} - -.container .jumbotron, -.container-fluid .jumbotron { - border-radius: 6px -} - -.jumbotron .container { - max-width: 100% -} - -@media screen and (min-width:768px) { - .jumbotron { - padding: 48px 0 - } - .container .jumbotron, - .container-fluid .jumbotron { - padding-right: 60px; - padding-left: 60px - } - .jumbotron .h1, - .jumbotron h1 { - font-size: 63px - } -} - -.thumbnail { - display: block; - padding: 4px; - margin-bottom: 20px; - line-height: 1.42857143; - background-color: #fff; - border: 1px solid #ddd; - border-radius: 4px; - -webkit-transition: border .2s ease-in-out; - -o-transition: border .2s ease-in-out; - transition: border .2s ease-in-out -} - -.thumbnail a>img, -.thumbnail>img { - margin-right: auto; - margin-left: auto -} - -a.thumbnail.active, -a.thumbnail:focus, -a.thumbnail:hover { - border-color: #337ab7 -} - -.thumbnail .caption { - padding: 9px; - color: #333 -} - -.alert { - padding: 15px; - margin-bottom: 20px; - border: 1px solid transparent; - border-radius: 4px -} - -.alert h4 { - margin-top: 0; - color: inherit -} - -.alert .alert-link { - font-weight: 700 -} - -.alert>p, -.alert>ul { - margin-bottom: 0 -} - -.alert>p+p { - margin-top: 5px -} - -.alert-dismissable, -.alert-dismissible { - padding-right: 35px -} - -.alert-dismissable .close, -.alert-dismissible .close { - position: relative; - top: -2px; - right: -21px; - color: inherit -} - -.alert-success { - color: #3c763d; - background-color: #dff0d8; - border-color: #d6e9c6 -} - -.alert-success hr { - border-top-color: #c9e2b3 -} - -.alert-success .alert-link { - color: #2b542c -} - -.alert-info { - color: #31708f; - background-color: #d9edf7; - border-color: #bce8f1 -} - -.alert-info hr { - border-top-color: #a6e1ec -} - -.alert-info .alert-link { - color: #245269 -} - -.alert-warning { - color: #8a6d3b; - background-color: #fcf8e3; - border-color: #faebcc -} - -.alert-warning hr { - border-top-color: #f7e1b5 -} - -.alert-warning .alert-link { - color: #66512c -} - -.alert-danger { - color: #a94442; - background-color: #f2dede; - border-color: #ebccd1 -} - -.alert-danger hr { - border-top-color: #e4b9c0 -} - -.alert-danger .alert-link { - color: #843534 -} - -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0 - } - to { - background-position: 0 0 - } -} - -@-o-keyframes progress-bar-stripes { - from { - background-position: 40px 0 - } - to { - background-position: 0 0 - } -} - -@keyframes progress-bar-stripes { - from { - background-position: 40px 0 - } - to { - background-position: 0 0 - } -} - -.progress { - height: 20px; - margin-bottom: 20px; - overflow: hidden; - background-color: #f5f5f5; - border-radius: 4px; -} - -.progress-bar { - float: left; - width: 0; - height: 100%; - font-size: 12px; - line-height: 20px; - color: #fff; - text-align: center; - background-color: #337ab7; - -webkit-transition: width .6s ease; - -o-transition: width .6s ease; - transition: width .6s ease -} - -.progress-bar-striped, -.progress-striped .progress-bar { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - -webkit-background-size: 40px 40px; - background-size: 40px 40px -} - -.progress-bar.active, -.progress.active .progress-bar { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite -} - -.progress-bar-success { - background-color: #5cb85c -} - -.progress-striped .progress-bar-success { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent) -} - -.progress-bar-info { - background-color: #5bc0de -} - -.progress-striped .progress-bar-info { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent) -} - -.progress-bar-warning { - background-color: #f0ad4e -} - -.progress-striped .progress-bar-warning { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent) -} - -.progress-bar-danger { - background-color: #d9534f -} - -.progress-striped .progress-bar-danger { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent) -} - -.media { - margin-top: 15px -} - -.media:first-child { - margin-top: 0 -} - -.media, -.media-body { - overflow: hidden; - zoom: 1 -} - -.media-body { - width: 10000px -} - -.media-object { - display: block -} - -.media-right, -.media>.pull-right { - padding-left: 10px -} - -.media-left, -.media>.pull-left { - padding-right: 10px -} - -.media-body, -.media-left, -.media-right { - display: table-cell; - vertical-align: top -} - -.media-middle { - vertical-align: middle -} - -.media-bottom { - vertical-align: bottom -} - -.media-heading { - margin-top: 0; - margin-bottom: 5px -} - -.media-list { - padding-left: 0; - list-style: none -} - -.list-group { - padding-left: 0; - margin-bottom: 20px -} - -.list-group-item { - position: relative; - display: block; - padding: 10px 15px; - margin-bottom: -1px; - background-color: #fff; - border: 1px solid #ddd -} - -.list-group-item:first-child { - border-top-left-radius: 4px; - border-top-right-radius: 4px -} - -.list-group-item:last-child { - margin-bottom: 0; - border-bottom-right-radius: 4px; - border-bottom-left-radius: 4px -} - -a.list-group-item { - color: #555 -} - -a.list-group-item .list-group-item-heading { - color: #333 -} - -a.list-group-item:focus, -a.list-group-item:hover { - color: #555; - text-decoration: none; - background-color: #f5f5f5 -} - -.list-group-item.disabled, -.list-group-item.disabled:focus, -.list-group-item.disabled:hover { - color: #777; - cursor: not-allowed; - background-color: #eee -} - -.list-group-item.disabled .list-group-item-heading, -.list-group-item.disabled:focus .list-group-item-heading, -.list-group-item.disabled:hover .list-group-item-heading { - color: inherit -} - -.list-group-item.disabled .list-group-item-text, -.list-group-item.disabled:focus .list-group-item-text, -.list-group-item.disabled:hover .list-group-item-text { - color: #777 -} - -.list-group-item.active, -.list-group-item.active:focus, -.list-group-item.active:hover { - z-index: 2; - color: #fff; - background-color: #337ab7; - border-color: #337ab7 -} - -.list-group-item.active .list-group-item-heading, -.list-group-item.active .list-group-item-heading>.small, -.list-group-item.active .list-group-item-heading>small, -.list-group-item.active:focus .list-group-item-heading, -.list-group-item.active:focus .list-group-item-heading>.small, -.list-group-item.active:focus .list-group-item-heading>small, -.list-group-item.active:hover .list-group-item-heading, -.list-group-item.active:hover .list-group-item-heading>.small, -.list-group-item.active:hover .list-group-item-heading>small { - color: inherit -} - -.list-group-item.active .list-group-item-text, -.list-group-item.active:focus .list-group-item-text, -.list-group-item.active:hover .list-group-item-text { - color: #c7ddef -} - -.list-group-item-success { - color: #3c763d; - background-color: #dff0d8 -} - -a.list-group-item-success { - color: #3c763d -} - -a.list-group-item-success .list-group-item-heading { - color: inherit -} - -a.list-group-item-success:focus, -a.list-group-item-success:hover { - color: #3c763d; - background-color: #d0e9c6 -} - -a.list-group-item-success.active, -a.list-group-item-success.active:focus, -a.list-group-item-success.active:hover { - color: #fff; - background-color: #3c763d; - border-color: #3c763d -} - -.list-group-item-info { - color: #31708f; - background-color: #d9edf7 -} - -a.list-group-item-info { - color: #31708f -} - -a.list-group-item-info .list-group-item-heading { - color: inherit -} - -a.list-group-item-info:focus, -a.list-group-item-info:hover { - color: #31708f; - background-color: #c4e3f3 -} - -a.list-group-item-info.active, -a.list-group-item-info.active:focus, -a.list-group-item-info.active:hover { - color: #fff; - background-color: #31708f; - border-color: #31708f -} - -.list-group-item-warning { - color: #8a6d3b; - background-color: #fcf8e3 -} - -a.list-group-item-warning { - color: #8a6d3b -} - -a.list-group-item-warning .list-group-item-heading { - color: inherit -} - -a.list-group-item-warning:focus, -a.list-group-item-warning:hover { - color: #8a6d3b; - background-color: #faf2cc -} - -a.list-group-item-warning.active, -a.list-group-item-warning.active:focus, -a.list-group-item-warning.active:hover { - color: #fff; - background-color: #8a6d3b; - border-color: #8a6d3b -} - -.list-group-item-danger { - color: #a94442; - background-color: #f2dede -} - -a.list-group-item-danger { - color: #a94442 -} - -a.list-group-item-danger .list-group-item-heading { - color: inherit -} - -a.list-group-item-danger:focus, -a.list-group-item-danger:hover { - color: #a94442; - background-color: #ebcccc -} - -a.list-group-item-danger.active, -a.list-group-item-danger.active:focus, -a.list-group-item-danger.active:hover { - color: #fff; - background-color: #a94442; - border-color: #a94442 -} - -.list-group-item-heading { - margin-top: 0; - margin-bottom: 5px -} - -.list-group-item-text { - margin-bottom: 0; - line-height: 1.3 -} - -.panel { - margin-bottom: 20px; - background-color: #fff; - border: 1px solid transparent; - border-radius: 4px; -} - -.panel-body { - padding: 15px -} - -.panel-heading { - padding: 10px 15px; - border-bottom: 1px solid transparent; - border-top-left-radius: 3px; - border-top-right-radius: 3px -} - -.panel-heading>.dropdown .dropdown-toggle { - color: inherit -} - -.panel-title { - margin-top: 0; - margin-bottom: 0; - font-size: 16px; - color: inherit -} - -.panel-title>.small, -.panel-title>.small>a, -.panel-title>a, -.panel-title>small, -.panel-title>small>a { - color: inherit -} - -.panel-footer { - padding: 10px 15px; - background-color: #f5f5f5; - border-top: 1px solid #ddd; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px -} - -.panel>.list-group, -.panel>.panel-collapse>.list-group { - margin-bottom: 0 -} - -.panel>.list-group .list-group-item, -.panel>.panel-collapse>.list-group .list-group-item { - border-width: 1px 0; - border-radius: 0 -} - -.panel>.list-group:first-child .list-group-item:first-child, -.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child { - border-top: 0; - border-top-left-radius: 3px; - border-top-right-radius: 3px -} - -.panel>.list-group:last-child .list-group-item:last-child, -.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child { - border-bottom: 0; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px -} - -.panel-heading+.list-group .list-group-item:first-child { - border-top-width: 0 -} - -.list-group+.panel-footer { - border-top-width: 0 -} - -.panel>.panel-collapse>.table, -.panel>.table, -.panel>.table-responsive>.table { - margin-bottom: 0 -} - -.panel>.panel-collapse>.table caption, -.panel>.table caption, -.panel>.table-responsive>.table caption { - padding-right: 15px; - padding-left: 15px -} - -.panel>.table-responsive:first-child>.table:first-child, -.panel>.table:first-child { - border-top-left-radius: 3px; - border-top-right-radius: 3px -} - -.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child, -.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child, -.panel>.table:first-child>tbody:first-child>tr:first-child, -.panel>.table:first-child>thead:first-child>tr:first-child { - border-top-left-radius: 3px; - border-top-right-radius: 3px -} - -.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child, -.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child, -.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child, -.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child, -.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child, -.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child, -.panel>.table:first-child>thead:first-child>tr:first-child td:first-child, -.panel>.table:first-child>thead:first-child>tr:first-child th:first-child { - border-top-left-radius: 3px -} - -.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child, -.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child, -.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child, -.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child, -.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child, -.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child, -.panel>.table:first-child>thead:first-child>tr:first-child td:last-child, -.panel>.table:first-child>thead:first-child>tr:first-child th:last-child { - border-top-right-radius: 3px -} - -.panel>.table-responsive:last-child>.table:last-child, -.panel>.table:last-child { - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px -} - -.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child, -.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child, -.panel>.table:last-child>tbody:last-child>tr:last-child, -.panel>.table:last-child>tfoot:last-child>tr:last-child { - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px -} - -.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child, -.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child, -.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child, -.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child, -.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child, -.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child, -.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child, -.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child { - border-bottom-left-radius: 3px -} - -.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child, -.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child, -.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child, -.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child, -.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child, -.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child, -.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child, -.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child { - border-bottom-right-radius: 3px -} - -.panel>.panel-body+.table, -.panel>.panel-body+.table-responsive, -.panel>.table+.panel-body, -.panel>.table-responsive+.panel-body { - border-top: 1px solid #ddd -} - -.panel>.table>tbody:first-child>tr:first-child td, -.panel>.table>tbody:first-child>tr:first-child th { - border-top: 0 -} - -.panel>.table-bordered, -.panel>.table-responsive>.table-bordered { - border: 0 -} - -.panel>.table-bordered>tbody>tr>td:first-child, -.panel>.table-bordered>tbody>tr>th:first-child, -.panel>.table-bordered>tfoot>tr>td:first-child, -.panel>.table-bordered>tfoot>tr>th:first-child, -.panel>.table-bordered>thead>tr>td:first-child, -.panel>.table-bordered>thead>tr>th:first-child, -.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child, -.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child, -.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child, -.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child, -.panel>.table-responsive>.table-bordered>thead>tr>td:first-child, -.panel>.table-responsive>.table-bordered>thead>tr>th:first-child { - border-left: 0 -} - -.panel>.table-bordered>tbody>tr>td:last-child, -.panel>.table-bordered>tbody>tr>th:last-child, -.panel>.table-bordered>tfoot>tr>td:last-child, -.panel>.table-bordered>tfoot>tr>th:last-child, -.panel>.table-bordered>thead>tr>td:last-child, -.panel>.table-bordered>thead>tr>th:last-child, -.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child, -.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child, -.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child, -.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child, -.panel>.table-responsive>.table-bordered>thead>tr>td:last-child, -.panel>.table-responsive>.table-bordered>thead>tr>th:last-child { - border-right: 0 -} - -.panel>.table-bordered>tbody>tr:first-child>td, -.panel>.table-bordered>tbody>tr:first-child>th, -.panel>.table-bordered>thead>tr:first-child>td, -.panel>.table-bordered>thead>tr:first-child>th, -.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td, -.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th, -.panel>.table-responsive>.table-bordered>thead>tr:first-child>td, -.panel>.table-responsive>.table-bordered>thead>tr:first-child>th { - border-bottom: 0 -} - -.panel>.table-bordered>tbody>tr:last-child>td, -.panel>.table-bordered>tbody>tr:last-child>th, -.panel>.table-bordered>tfoot>tr:last-child>td, -.panel>.table-bordered>tfoot>tr:last-child>th, -.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td, -.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th, -.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td, -.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th { - border-bottom: 0 -} - -.panel>.table-responsive { - margin-bottom: 0; - border: 0 -} - -.panel-group { - margin-bottom: 20px -} - -.panel-group .panel { - margin-bottom: 0; - border-radius: 4px -} - -.panel-group .panel+.panel { - margin-top: 5px -} - -.panel-group .panel-heading { - border-bottom: 0 -} - -.panel-group .panel-heading+.panel-collapse>.list-group, -.panel-group .panel-heading+.panel-collapse>.panel-body { - border-top: 1px solid #ddd -} - -.panel-group .panel-footer { - border-top: 0 -} - -.panel-group .panel-footer+.panel-collapse .panel-body { - border-bottom: 1px solid #ddd -} - -.panel-default { - border-color: #ddd -} - -.panel-default>.panel-heading { - color: #333; - background-color: #f5f5f5; - border-color: #ddd -} - -.panel-default>.panel-heading+.panel-collapse>.panel-body { - border-top-color: #ddd -} - -.panel-default>.panel-heading .badge { - color: #f5f5f5; - background-color: #333 -} - -.panel-default>.panel-footer+.panel-collapse>.panel-body { - border-bottom-color: #ddd -} - -.panel-primary { - border-color: #337ab7 -} - -.panel-primary>.panel-heading { - color: #fff; - background-color: #337ab7; - border-color: #337ab7 -} - -.panel-primary>.panel-heading+.panel-collapse>.panel-body { - border-top-color: #337ab7 -} - -.panel-primary>.panel-heading .badge { - color: #337ab7; - background-color: #fff -} - -.panel-primary>.panel-footer+.panel-collapse>.panel-body { - border-bottom-color: #337ab7 -} - -.panel-success { - border-color: #d6e9c6 -} - -.panel-success>.panel-heading { - color: #3c763d; - background-color: #dff0d8; - border-color: #d6e9c6 -} - -.panel-success>.panel-heading+.panel-collapse>.panel-body { - border-top-color: #d6e9c6 -} - -.panel-success>.panel-heading .badge { - color: #dff0d8; - background-color: #3c763d -} - -.panel-success>.panel-footer+.panel-collapse>.panel-body { - border-bottom-color: #d6e9c6 -} - -.panel-info { - border-color: #bce8f1 -} - -.panel-info>.panel-heading { - color: #31708f; - background-color: #d9edf7; - border-color: #bce8f1 -} - -.panel-info>.panel-heading+.panel-collapse>.panel-body { - border-top-color: #bce8f1 -} - -.panel-info>.panel-heading .badge { - color: #d9edf7; - background-color: #31708f -} - -.panel-info>.panel-footer+.panel-collapse>.panel-body { - border-bottom-color: #bce8f1 -} - -.panel-warning { - border-color: #faebcc -} - -.panel-warning>.panel-heading { - color: #8a6d3b; - background-color: #fcf8e3; - border-color: #faebcc -} - -.panel-warning>.panel-heading+.panel-collapse>.panel-body { - border-top-color: #faebcc -} - -.panel-warning>.panel-heading .badge { - color: #fcf8e3; - background-color: #8a6d3b -} - -.panel-warning>.panel-footer+.panel-collapse>.panel-body { - border-bottom-color: #faebcc -} - -.panel-danger { - border-color: #ebccd1 -} - -.panel-danger>.panel-heading { - color: #a94442; - background-color: #f2dede; - border-color: #ebccd1 -} - -.panel-danger>.panel-heading+.panel-collapse>.panel-body { - border-top-color: #ebccd1 -} - -.panel-danger>.panel-heading .badge { - color: #f2dede; - background-color: #a94442 -} - -.panel-danger>.panel-footer+.panel-collapse>.panel-body { - border-bottom-color: #ebccd1 -} - -.embed-responsive { - position: relative; - display: block; - height: 0; - padding: 0; - overflow: hidden -} - -.embed-responsive .embed-responsive-item, -.embed-responsive embed, -.embed-responsive iframe, -.embed-responsive object, -.embed-responsive video { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 100%; - height: 100%; - border: 0 -} - -.embed-responsive.embed-responsive-16by9 { - padding-bottom: 56.25% -} - -.embed-responsive.embed-responsive-4by3 { - padding-bottom: 75% -} - -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #f5f5f5; - border: 1px solid #e3e3e3; - border-radius: 4px; -} - -.well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, .15) -} - -.well-lg { - padding: 24px; - border-radius: 6px -} - -.well-sm { - padding: 9px; - border-radius: 3px -} - -.close { - float: right; - font-size: 21px; - font-weight: 700; - line-height: 1; - color: #000; - filter: alpha(opacity=20); - opacity: .2 -} - -.close:focus, -.close:hover { - color: #000; - text-decoration: none; - cursor: pointer; - filter: alpha(opacity=50); - opacity: .5 -} - -button.close { - -webkit-appearance: none; - padding: 0; - cursor: pointer; - background: 0 0; - border: 0 -} - -.modal-open { - overflow: hidden -} - -.modal { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - display: none; - overflow: hidden; - -webkit-overflow-scrolling: touch; - outline: 0 -} - -.modal.fade .modal-dialog { - -webkit-transition: -webkit-transform .3s ease-out; - -o-transition: -o-transform .3s ease-out; - transition: transform .3s ease-out; - -webkit-transform: translate(0, -25%); - -ms-transform: translate(0, -25%); - -o-transform: translate(0, -25%); - transform: translate(0, -25%) -} - -.modal.in .modal-dialog { - -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - -o-transform: translate(0, 0); - transform: translate(0, 0) -} - -.modal-open .modal { - overflow-x: hidden; - overflow-y: auto -} - -.modal-dialog { - position: relative; - width: auto; - margin: 10px -} - -.modal-content { - position: relative; - background-color: #fff; - -webkit-background-clip: padding-box; - background-clip: padding-box; - border: 1px solid #999; - border: 1px solid rgba(0, 0, 0, .2); - border-radius: 6px; - outline: 0; -} - -.modal-backdrop { - position: absolute; - top: 0; - right: 0; - left: 0; - background-color: #000 -} - -.modal-backdrop.fade { - filter: alpha(opacity=0); - opacity: 0 -} - -.modal-backdrop.in { - filter: alpha(opacity=50); - opacity: .5 -} - -.modal-header { - min-height: 16.43px; - padding: 15px; - border-bottom: 1px solid #e5e5e5 -} - -.modal-header .close { - margin-top: -2px -} - -.modal-title { - margin: 0; - line-height: 1.42857143 -} - -.modal-body { - position: relative; - padding: 15px -} - -.modal-footer { - padding: 15px; - text-align: right; - border-top: 1px solid #e5e5e5 -} - -.modal-footer .btn+.btn { - margin-bottom: 0; - margin-left: 5px -} - -.modal-footer .btn-group .btn+.btn { - margin-left: -1px -} - -.modal-footer .btn-block+.btn-block { - margin-left: 0 -} - -.modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll -} - -@media (min-width:768px) { - .modal-dialog { - width: 600px; - margin: 30px auto - } - .modal-content { - } - .modal-sm { - width: 300px - } -} - -@media (min-width:992px) { - .modal-lg { - width: 900px - } -} - -.tooltip { - position: absolute; - z-index: 1070; - display: block; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 12px; - font-weight: 400; - line-height: 1.4; - visibility: visible; - filter: alpha(opacity=0); - opacity: 0 -} - -.tooltip.in { - filter: alpha(opacity=90); - opacity: .9 -} - -.tooltip.top { - padding: 5px 0; - margin-top: -3px -} - -.tooltip.right { - padding: 0 5px; - margin-left: 3px -} - -.tooltip.bottom { - padding: 5px 0; - margin-top: 3px -} - -.tooltip.left { - padding: 0 5px; - margin-left: -3px -} - -.tooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #fff; - text-align: center; - text-decoration: none; - background-color: #000; - border-radius: 4px -} - -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid -} - -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-width: 5px 5px 0; - border-top-color: #000 -} - -.tooltip.top-left .tooltip-arrow { - right: 5px; - bottom: 0; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000 -} - -.tooltip.top-right .tooltip-arrow { - bottom: 0; - left: 5px; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000 -} - -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: #000 -} - -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: #000 -} - -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000 -} - -.tooltip.bottom-left .tooltip-arrow { - top: 0; - right: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000 -} - -.tooltip.bottom-right .tooltip-arrow { - top: 0; - left: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000 -} - -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1060; - display: none; - max-width: 276px; - padding: 1px; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - font-weight: 400; - line-height: 1.42857143; - text-align: left; - white-space: normal; - background-color: #fff; - -webkit-background-clip: padding-box; - background-clip: padding-box; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, .2); - border-radius: 6px; -} - -.popover.top { - margin-top: -10px -} - -.popover.right { - margin-left: 10px -} - -.popover.bottom { - margin-top: 10px -} - -.popover.left { - margin-left: -10px -} - -.popover-title { - padding: 8px 14px; - margin: 0; - font-size: 14px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - border-radius: 5px 5px 0 0 -} - -.popover-content { - padding: 9px 14px -} - -.popover>.arrow, -.popover>.arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid -} - -.popover>.arrow { - border-width: 11px -} - -.popover>.arrow:after { - content: ""; - border-width: 10px -} - -.popover.top>.arrow { - bottom: -11px; - left: 50%; - margin-left: -11px; - border-top-color: #999; - border-top-color: rgba(0, 0, 0, .25); - border-bottom-width: 0 -} - -.popover.top>.arrow:after { - bottom: 1px; - margin-left: -10px; - content: " "; - border-top-color: #fff; - border-bottom-width: 0 -} - -.popover.right>.arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-right-color: #999; - border-right-color: rgba(0, 0, 0, .25); - border-left-width: 0 -} - -.popover.right>.arrow:after { - bottom: -10px; - left: 1px; - content: " "; - border-right-color: #fff; - border-left-width: 0 -} - -.popover.bottom>.arrow { - top: -11px; - left: 50%; - margin-left: -11px; - border-top-width: 0; - border-bottom-color: #999; - border-bottom-color: rgba(0, 0, 0, .25) -} - -.popover.bottom>.arrow:after { - top: 1px; - margin-left: -10px; - content: " "; - border-top-width: 0; - border-bottom-color: #fff -} - -.popover.left>.arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-right-width: 0; - border-left-color: #999; - border-left-color: rgba(0, 0, 0, .25) -} - -.popover.left>.arrow:after { - right: 1px; - bottom: -10px; - content: " "; - border-right-width: 0; - border-left-color: #fff -} - - -@media screen and (min-width:768px) { - .carousel-control .glyphicon-chevron-left, - .carousel-control .glyphicon-chevron-right, - .carousel-control .icon-next, - .carousel-control .icon-prev { - width: 30px; - height: 30px; - margin-top: -15px; - font-size: 30px - } - .carousel-control .glyphicon-chevron-left, - .carousel-control .icon-prev { - margin-left: -15px - } - .carousel-control .glyphicon-chevron-right, - .carousel-control .icon-next { - margin-right: -15px - } - .carousel-caption { - right: 20%; - left: 20%; - padding-bottom: 30px - } - .carousel-indicators { - bottom: 20px - } -} - -.btn-group-vertical>.btn-group:after, -.btn-group-vertical>.btn-group:before, -.btn-toolbar:after, -.btn-toolbar:before, -.clearfix:after, -.clearfix:before, -.container-fluid:after, -.container-fluid:before, -.container:after, -.container:before, -.dl-horizontal dd:after, -.dl-horizontal dd:before, -.form-horizontal .form-group:after, -.form-horizontal .form-group:before, -.modal-footer:after, -.modal-footer:before, -.nav:after, -.nav:before, -.navbar-collapse:after, -.navbar-collapse:before, -.navbar-header:after, -.navbar-header:before, -.navbar:after, -.navbar:before, -.pager:after, -.pager:before, -.panel-body:after, -.panel-body:before, -.row:after, -.row:before { - display: table; - content: " " -} - -.btn-group-vertical>.btn-group:after, -.btn-toolbar:after, -.clearfix:after, -.container-fluid:after, -.container:after, -.dl-horizontal dd:after, -.form-horizontal .form-group:after, -.modal-footer:after, -.nav:after, -.navbar-collapse:after, -.navbar-header:after, -.navbar:after, -.pager:after, -.panel-body:after, -.row:after { - clear: both -} - -.center-block { - display: block; - margin-right: auto; - margin-left: auto -} - -.pull-right { - float: right!important -} - -.pull-left { - float: left!important -} - -.hide { - display: none!important -} - -.show { - display: block!important -} - -.invisible { - visibility: hidden -} - -.text-hide { - font: 0/0 a; - color: transparent; - background-color: transparent; - border: 0 -} - -.hidden { - display: none!important; - visibility: hidden!important -} - -.affix { - position: fixed -} - -@-ms-viewport { - width: device-width -} - -.visible-lg, -.visible-md, -.visible-sm, -.visible-xs { - display: none!important -} - -.visible-lg-block, -.visible-lg-inline, -.visible-lg-inline-block, -.visible-md-block, -.visible-md-inline, -.visible-md-inline-block, -.visible-sm-block, -.visible-sm-inline, -.visible-sm-inline-block, -.visible-xs-block, -.visible-xs-inline, -.visible-xs-inline-block { - display: none!important -} - -@media (max-width:767px) { - .visible-xs { - display: block!important - } - table.visible-xs { - display: table - } - tr.visible-xs { - display: table-row!important - } - td.visible-xs, - th.visible-xs { - display: table-cell!important - } -} - -@media (max-width:767px) { - .visible-xs-block { - display: block!important - } -} - -@media (max-width:767px) { - .visible-xs-inline { - display: inline!important - } -} - -@media (max-width:767px) { - .visible-xs-inline-block { - display: inline-block!important - } -} - -@media (min-width:768px) and (max-width:991px) { - .visible-sm { - display: block!important - } - table.visible-sm { - display: table - } - tr.visible-sm { - display: table-row!important - } - td.visible-sm, - th.visible-sm { - display: table-cell!important - } -} - -@media (min-width:768px) and (max-width:991px) { - .visible-sm-block { - display: block!important - } -} - -@media (min-width:768px) and (max-width:991px) { - .visible-sm-inline { - display: inline!important - } -} - -@media (min-width:768px) and (max-width:991px) { - .visible-sm-inline-block { - display: inline-block!important - } -} - -@media (min-width:992px) and (max-width:1199px) { - .visible-md { - display: block!important - } - table.visible-md { - display: table - } - tr.visible-md { - display: table-row!important - } - td.visible-md, - th.visible-md { - display: table-cell!important - } -} - -@media (min-width:992px) and (max-width:1199px) { - .visible-md-block { - display: block!important - } -} - -@media (min-width:992px) and (max-width:1199px) { - .visible-md-inline { - display: inline!important - } -} - -@media (min-width:992px) and (max-width:1199px) { - .visible-md-inline-block { - display: inline-block!important - } -} - -@media (min-width:1200px) { - .visible-lg { - display: block!important - } - table.visible-lg { - display: table - } - tr.visible-lg { - display: table-row!important - } - td.visible-lg, - th.visible-lg { - display: table-cell!important - } -} - -@media (min-width:1200px) { - .visible-lg-block { - display: block!important - } -} - -@media (min-width:1200px) { - .visible-lg-inline { - display: inline!important - } -} - -@media (min-width:1200px) { - .visible-lg-inline-block { - display: inline-block!important - } -} - -@media (max-width:767px) { - .hidden-xs { - display: none!important - } -} - -@media (min-width:768px) and (max-width:991px) { - .hidden-sm { - display: none!important - } -} - -@media (min-width:992px) and (max-width:1199px) { - .hidden-md { - display: none!important - } -} - -@media (min-width:1200px) { - .hidden-lg { - display: none!important - } -} - -.visible-print { - display: none!important -} - -@media print { - .visible-print { - display: block!important - } - table.visible-print { - display: table - } - tr.visible-print { - display: table-row!important - } - td.visible-print, - th.visible-print { - display: table-cell!important - } -} - -.visible-print-block { - display: none!important -} - -@media print { - .visible-print-block { - display: block!important - } -} - -.visible-print-inline { - display: none!important -} - -@media print { - .visible-print-inline { - display: inline!important - } -} - -.visible-print-inline-block { - display: none!important -} - -@media print { - .visible-print-inline-block { - display: inline-block!important - } -} - -@media print { - .hidden-print { - display: none!important - } -} diff --git a/docs/css/boxshadowproperties.css b/docs/css/boxshadowproperties.css deleted file mode 100644 index 0f2e1e6..0000000 --- a/docs/css/boxshadowproperties.css +++ /dev/null @@ -1,24 +0,0 @@ -/* box-shadow fonts return errors with prince, so extracting here to put in web output only */ - -#search-demo-container ul#results-container { - box-shadow: 2px 3px 2px #dedede; -} - - -hr.shaded { - box-shadow: inset 0 6px 6px -6px rgba(0,0,0,0.5); -} - -.videoThumbs img { - box-shadow: 2px 2px 1px #f0f0f0; -} - -.box { - box-shadow: 2px 2px 4px #dedede; -} - -@media (max-width: 1200px) { - .navbar-collapse { - box-shadow: inset 0 1px 0 rgba(255,255,255,0.1); - } -} diff --git a/docs/css/customstyles.css b/docs/css/customstyles.css deleted file mode 100644 index e3f1532..0000000 --- a/docs/css/customstyles.css +++ /dev/null @@ -1,1306 +0,0 @@ -.anchor-link { - display: none; -} - -body { - font-size:15px; -} - -.bs-callout { - padding: 20px; - margin: 20px 0; - border: 1px solid #eee; - border-left-width: 5px; - border-radius: 3px; -} -.bs-callout h4 { - margin-top: 0; - margin-bottom: 5px; -} -.bs-callout p:last-child { - margin-bottom: 0; -} -.bs-callout code { - border-radius: 3px; -} -.bs-callout+.bs-callout { - margin-top: -5px; -} -.bs-callout-default { - border-left-color: #777; -} -.bs-callout-default h4 { - color: #777; -} -.bs-callout-primary { - border-left-color: #428bca; -} -.bs-callout-primary h4 { - color: #428bca; -} -.bs-callout-success { - border-left-color: #5cb85c; -} -.bs-callout-success h4 { - color: #5cb85c; -} -.bs-callout-danger { - border-left-color: #d9534f; -} -.bs-callout-danger h4 { - color: #d9534f; -} -.bs-callout-warning { - border-left-color: #f0ad4e; -} -.bs-callout-warning h4 { - color: #f0ad4e; -} -.bs-callout-info { - border-left-color: #5bc0de; -} -.bs-callout-info h4 { - color: #5bc0de; -} - - -.gi-2x{font-size: 2em;} -.gi-3x{font-size: 3em;} -.gi-4x{font-size: 4em;} -.gi-5x{font-size: 5em;} - - -.breadcrumb > .active {color: #777 !important;} - -/* make room for the nav bar */ -h1[id] -/*,h2[id], -h3[id], -h4[id], -h5[id], -h6[id], -dt[id]*/ -{ -padding-top: 60px; -margin-top: -40px -} - -.output_html a{ - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - margin: 25px 0px; - display: block; - padding: 9.5px; - font-size: 13px; - line-height: 1.42857143; - color: #333; - word-break: break-all; - word-wrap: break-word; - background-color: #F5F5F5; - border: 1px solid #FFA500; - border-radius: 4px; - white-space: pre-wrap; - box-sizing: border-box; - overflow: auto; -} - -.col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9 { - float: left; -} - -.col-md-9 { - width: 75%; -} - -/* From: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_download_button' */ -.cstm_btn a{ - background-color: DodgerBlue; - border: none; - color: white; - padding: 12px 30px; - cursor: pointer; - font-size: 20px; - box-sizing: 15px; - position: absolute; -} - -/* Darker background on mouse-over */ -.cstm_btn a:hover { - background-color: RoyalBlue; -} - -.container #notebook-container{ - width: 100%; - box-sizing: border-box; - } - -.post-content img { - margin: 12px 0px 3px 0px; - width: auto; - height: auto; - max-width: 100%; - max-height: 100%; -} - -.post-content ol li, .post-content ul li { - margin: 10px 0px; -} - -.pageSummary { - font-size:13px; - display:block; - margin-bottom:15px; - padding-left:20px; -} - -.post-summary { - margin-bottom:12px; -} - -.bs-example{ - margin: 20px; -} - -.breadcrumb li { - color: gray; -} - -table { - background-color: transparent; -} -caption { - padding-top: 8px; - padding-bottom: 8px; - color: #777; - text-align: left; -} -th { - text-align: left; -} -table { - max-width: 90%; - margin-bottom: 20px; - border: 1px solid #dedede; -} - -table > thead > tr > th, -table > tbody > tr > th, -table > tfoot > tr > th, -table > thead > tr > td, -table > tbody > tr > td, -table > tfoot > tr > td { - padding: 8px; - line-height: 1.42857143; - vertical-align: top; - border-top: 1px solid #ddd; -} -table > thead > tr > th { - vertical-align: bottom; - border-bottom: 2px solid #ddd; - text-transform: none; - background-color: #777; - color: white; - text-align: left; -} -table > caption + thead > tr:first-child > th, -table > colgroup + thead > tr:first-child > th, -table > thead:first-child > tr:first-child > th, -table > caption + thead > tr:first-child > td, -table > colgroup + thead > tr:first-child > td, -table > thead:first-child > tr:first-child > td { - border-top: 0; -} - -table > tbody > tr:nth-of-type(odd) { - background-color: #f9f9f9; -} - -table col[class*="col-"] { - position: static; - display: table-column; - float: none; -} -table td[class*="col-"], -table th[class*="col-"] { - position: static; - display: table-cell; - float: none; -} - -table tr td { - hyphens: auto; -} - - -p.external a { - text-align:right; - font-size:12px; - color: #0088cc; - display:inline; -} - -#definition-box-container div a.active { - font-weight: bold; -} -p.post-meta {font-size: 80%; color: #777;} - -.entry-date{font-size:14px;font-size:0.875rem;line-height:1.71429;margin-bottom:0;text-transform:uppercase;} - -/* search area */ -#search-demo-container ul#results-container { - list-style: none; - font-size: 12px; - background-color: white; - position: absolute; - top: 40px; /* if you change anything about the nav, you'll prob. need to reset the top and left values here.*/ - left: 20px; - z-index: -1; - width:223px; - border-left: 1px solid #dedede; -} - - -ul#results-container a { - background-color: transparent; -} - -ul#results-container a:hover { - color: black; -} - - -#search-demo-container a:hover { - color: black; -} -#search-input { - padding: .5em; - margin-left:20px; - width:20em; - font-size: 0.8em; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - margin-top:10px; -} -/* end search */ - -.filter-options { - margin-bottom: 20px; -} -.filter-options button { - margin: 3px; -} - -a.source_link { - float:right; - font-size:15px; - font-weight:normal; -} - -div#toc ul { - font-size: 90%; - background-color: whitesmoke; - padding: 5px; - border-radius: 5px; - max-width: 450px; - color: gray; - list-style-type: none; -} - -/* when using relative fonts like 0.9em or 90%, remember to then set the nested items to 1em or 100%, otherwise each level will get smaller and smaller and less readable */ -div#toc ul li { - margin: 8px 0px 8px 22px; - font-size: 100%; - list-style-type: none; -} - -div#toc ul li ul { - font-size: 100%; - padding-left:30px; - padding-top: 0px; - padding-bottom: 0px; - list-style-type: none; -} - -div#toc ul li ul li.hide_content::before { - content: none; -} - -div#toc >ul::before { - content: "Table of Contents"; - font-weight: 500; - color: #555; - text-align:center; - margin-left:auto; - margin-right:auto; - width:70px; - padding-top:150px; - padding-bottom:40px; - padding-left:10px; -} - -li.dropdownActive a { - font-weight: bold; -} - - -.post-content a.fa-rss { - color: orange; -} - - -.navbar-inverse .navbar-nav > li > a { - background-color: transparent; - margin-top:10px; -} - -.post-content .rssfeedLink { - color: #248EC2; -} - -footer { - font-size: smaller; -} - -/* FAQ page */ -#accordion .panel-heading { - font-size: 12px; -} - -a.accordion-toggle, a.accordion-collapsed { - font-size: 14px; - text-decoration: none; -} - -/* navgoco sidebar styles (customized) */ -.nav, .nav ul, .nav li { - list-style: none; -} - -.nav ul { - padding: 0; - /*margin: 0 0 0 18px;*/ - margin:0px; -} - -.nav { - /* padding: 4px;*/ - padding:0px; - margin: 0px; -} - -.nav > li { - margin: 1px 0; -} - -.nav > li li { - margin: 2px 0; -} - -.nav a { - color: #333; - display: block; - outline: none; - /*-webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px;*/ - text-decoration: none; -} - -.nav li > a > span { - float: right; - font-size: 19px; - font-weight: bolder; -} - - -.nav li > a > span:after { - content: '\25be'; -} -.nav li.active > a > span:after { - content: '\25b4'; -} - -.nav a:hover, .nav li.active > a { - background-color: #8D8D8D; - color: #f5f5f5; -} - -.nav > li.active > a { -background-color: #347DBE; -} - -.nav li a { - font-size: 12px; - line-height: 18px; - padding: 2px 10px; - background-color: #f1f1f1; -} - -.nav > li > a { - font-size: 14px; - line-height: 20px; - padding: 4px 10px; -} - -ul#mysidebar { - border-radius:0px; -} - -.nav ul li ul li a { - padding-left:40px; -} - -.nav li.thirdlevel > a { - color: #248EC2; - font-weight:bold; - padding-left:20px; - background-color: whitesmoke !important; -} - - -.nav ul li a { - background-color: #FAFAFA; -} - -.nav li a { - padding-right:10px; -} - -.nav li a:hover { - background-color: #8D8D8D; -} - -.nav ul li a { - border-top:1px solid whitesmoke; - padding-left:10px; -} -/* end sidebar */ - -.navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus { - border-radius:5px; -} - -.navbar-inverse .navbar-nav>.open>a, .navbar-inverse .navbar-nav>.open>a:focus, .navbar-inverse .navbar-nav>.open>a:hover { - border-radius: 5px; -} - -span.projectTitle { - font-family: Helvetica; - font-weight: bold; -} - -.footer { - text-align: right; -} - -.footerMeta { - background-color: whitesmoke; - padding: 10px; - max-width: 250px; - border-radius: 5px; - margin-top: 50px; - font-style:italic; - font-size:12px; -} - -img.screenshotSmall { - max-width: 300px; -} - - -dl dt p { - margin-left:20px; -} - - -dl dd { - margin-top:10px; - margin-bottom:10px; -} - -dl.dl-horizontal dd { - padding-top: 20px; -} - -figcaption { - - padding-bottom:12px; - padding-top:6px; - max-width: 90%; - margin-bottom:20px; - font-style: italic; - color: gray; - -} - -.testing { - color: orange; -} - -.preference { - color: red; -} - - -table.dataTable thead { - background-color: #444; -} -table td { - hyphens: auto; -} - -section table tr.success { - background-color: #dff0d8 !important; -} - -table tr.info { - background-color: #d9edf7 !important; -} - -section table tr.warning, table tr.testing, table tr.testing > td.sorting_1 { - background-color: #fcf8e3 !important; -} -section table tr.danger, table tr.preference, table tr.preference > td.sorting_1 { - background-color: #f2dede !important; -} - -.orange { - color: orange; -} - -table.profile thead tr th { - background-color: #248ec2; -} - -table.request thead tr th { - background-color: #ED1951; -} - -.audienceLabel { - margin: 10px; - float: right; - border:1px solid #dedede; - padding:7px; -} - -.prefaceAudienceLabel { - color: gray; - text-align: center; - margin:5px; -} -span.myLabel { - padding-left:10px; - padding-right:10px; -} - -button.cursorNorm { - cursor: default; -} - -a.dropdown-toggle, .navbar-inverse .navbar-nav > li > a { - margin-left: 10px; -} - -hr.faded { - border: 0; - height: 1px; - background-image: -webkit-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0)); - background-image: -moz-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0)); - background-image: -ms-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0)); - background-image: -o-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0)); -} - -hr.shaded { - height: 12px; - border: 0; - margin-top: 70px; - background: white; - width: 100%; - margin-bottom: 10px; -} - -.fa-6x{font-size:900%;} -.fa-7x{font-size:1100%;} -.fa-8x{font-size:1300%;} -.fa-9x{font-size:1500%;} -.fa-10x{font-size:1700%;} - -i.border { - padding: 10px 20px; - background-color: whitesmoke; -} - -a[data-toggle] { - color: #248EC2; -} - -.summary { - font-size:120%; - color: #808080; - margin:20px 0px 20px 0px; - border-left: 5px solid #ED1951; - padding-left: 10px; - -} - -a.fa.fa-envelope-o.mailto { - font-weight: 600; -} - -h3 {color: #ED1951; font-weight:normal; font-size:130%;} -h4 {color: #000000; font-weight:normal; font-size:120%; font-weight:bold;} - -.alert, .callout { - overflow: hidden; -} - -.nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus { - background-color: #248ec2; - color: white; -} - -ol li ol li {list-style-type: lower-alpha;} -ol li ul li {list-style-type: disc;} - -li img {clear:both; } - -div#toc ul li ul li { - list-style-type: none; - margin: 5px 0px 0px 0px; -} - -.tab-content { - padding: 15px; - background-color: #FAFAFA; -} - -span.tagTitle {font-weight: 500;} - -li.activeSeries { - font-weight: bold; -} - -.seriesContext .dropdown-menu li.active { - font-weight: bold; - margin-left: 43px; - font-size:18px; -} - -.alert-warning { - color: #444; -} - -div.alert code, h2 code { - background-color: transparent !important; -} -/* without this, the links in these notes aren't visible.*/ -.alert a { - text-decoration: underline; -} - -div.tags {padding: 10px 5px;} - -.tabLabel { - font-weight: normal; -} - -hr { - background: #999; - margin: 30px 0px; - width: 90%; - margin-left: auto; - margin-right: auto; -} - -button.cursorNorm { - cursor: pointer; -} - -h2 { - font-size:24px; - line-height:29px; - border-top: 3px solid blue; - padding-top: 5px; -} - -span.otherProgrammingLanguages { - font-style: normal; -} - -a[data-toggle="tooltip"] { - color: #649345; - font-style: italic; - cursor: default; -} - -.seriesNext, .seriesContext { - margin-top: 15px; - margin-bottom: 15px; -} - -.seriescontext ol li { - list-style-type: upper-roman; -} - -ol.series li { - list-style-type: decimal; - margin-left: 40px; - padding-left: 0px; -} - -.siteTagline { - font-size: 200%; - font-weight: bold; - color: silver; - font-family: monospace; - text-align: center; - line-height: 10px; - margin: 20px 0px; - display: block; -} - -.versionTagline { - text-align: center; - margin-bottom: 20px; - font-family: courier; - color: silver; - color: #444; - display:block; -} - -/* not sure if using this ...*/ -.navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { - border-color: #248ec2 !important; -} - -#mysidebar .nav ul { - background-color: #FAFAFA; -} -.nav ul.series li { - list-style: decimal; - font-size:12px; -} - -.nav ul.series li a:hover { - background-color: gray; -} -.nav ul.series { - padding-left: 30px; -} - -.nav ul.series { - background-color: #FAFAFA; -} - -/* -a.dropdown-toggle.otherProgLangs { - color: #f7e68f !important; -} -*/ - -span.muted {color: #666;} - -table code {background-color: transparent;} - -.highlight .err { - color: #a61717; - background-color: transparent !important; -} - -table p { - margin-top: 12px; - margin-bottom: 12px; -} - -pre, table code { - white-space: pre-wrap; /* css-3 */ - white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ - word-wrap: break-word; /* Internet Explorer 5.5+ */ -} - -pre { - margin: 25px 0px; -} - -#json-box-container pre { - margin: 0px; -} - -.video-js { - margin: 30px 0px; -} - -video { - display: block; - margin: 30px 0px; - border: 1px solid #c0c0c0; -} - - -p.required, p.dataType {display: block; color: #c0c0c0; font-size: 80%; margin-left:4px;} - -dd {margin-left:20px;} - -.post-content img.inline { - margin:0px; - margin-bottom:6px; -} -.panel-heading { - font-weight: bold; -} - -.note code, .alert code, .warning code, div#toc code, h2 code, h3 code, h4 code { - color: inherit; - padding: 0px; -} - -.alert { - margin-bottom:10px; - margin-top:10px; -} - -a.accordion-toggle { - font-style: normal; -} - -span.red { - color: red; - font-family: Monaco, Menlo, Consolas, "Courier New", monospace; -} - -h3.codeExplanation { - font-size:18px; - font-style:normal; - color: black; - line-height: 24px; -} - -span.soft { - color: #c0c0c0; -} - -.githubEditButton { - margin-bottom:7px; -} - -.endpoint { - padding: 15px; - background-color: #f0f0f0; - font-family: courier; - font-size: 110%; - margin: 20px 0px; - color: #444; -} - -.parameter { - font-family: courier; - color: red !important; -} - -.formBoundary { - border: 1px solid gray; - padding: 15px; - margin: 15px 0px; - background-color: whitesmoke; -} - -@media (max-width: 767px) { - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { - color: #444; - } -} - -@media (max-width: 990px) { - #mysidebar { - position: relative; - } - .col-md-9 { - width: 95%; - } -} - - -@media (min-width: 1000px) { - - ul#mysidebar { - width: 225px; - } -} - -@media (max-width: 900px) { - - ul#mysidebar { - max-width: 100%; - } -} - -.col-md-9 img { - max-width: 100%; - max-height: 100%; -} - - -.post-content img { - margin: 12px 0px 3px 0px; - width: auto; - height: auto; - max-width: 100%; - max-height: 100%; -} -.col-md-9 img { - max-width: 100%; - max-height: 100%; -} - - -.post-content img { - margin: 12px 0px 3px 0px; - width: auto; - height: auto; - max-width: 100%; - max-height: 100%; -} - -.videoThumbs img { - float: left; - margin:15px 15px 15px 0px; - border: 1px solid #dedede; -} - - -@media only screen and (min-width: 900px), only screen and (min-device-width: 900px) { - .col-md-9 img { - max-width: 990px; - max-height: 700px; - } -} - -*:hover > .anchorjs-link { - transition: color .25s linear; - text-decoration: none; -} - -.kbCaption { - color: white; - background-color: #444; - padding:10px; -} - -/* Strip the outbound icon when this class is present */ -a[href].noCrossRef::after, -a.no_icon:after - { - content:"" !important; - padding-left: 0; -} - -.btn-default { - margin-bottom: 10px; -} - -/* algolia search */ - -.search { - text-align: left; -} -.search input { - font-size: 20px; - width: 300px; -} -.results { - margin: auto; - text-align: left; -} -.results ul { - list-style-type: none; - padding: 0; -} - -/* algolia */ - -div.results { - position: absolute; - background-color: white; - width: 100%; -} - -.post-meta { - font-size: 14px; - color: #828282; -} - -.post-link { - font-size: 22px; -} - -.post-list p { - margin: 10px 0px; -} - -time { - margin-right: 10px; -} - -p.post-meta time { - margin-right: 0px; -} - -span.label.label-default { - background-color: gray; -} - -span.label.label-primary { - background-color: #f0ad4e; -} -.col-lg-12 .nav li a {background-color: white} - - -.nav li.active > a.subfoldersTitle { - background-color: whitesmoke; - font-weight: bold; - color: black; - } - -code { - color: #1d1f5b; - background-color: #f3f3f3; -} - -a code { - color: #0082C2; -} - -table th code { - color: white; -} - -ol li ul li ol li { - list-style: decimal; -} - -ol li ul li ol li ul li{ - list-style: disc; -} - -.post-content table th { - vertical-align: top; -} - -table thead th code.highlighter-rouge { - background-color: transparent; -} - - -.box { - padding: 10px; - border: 1px solid #888; - width: 100px; - height: 80px; - background-color: #f5f5f5; - font-family: Arial; - font-size: 12px; - hyphens: auto; - float: left; - font-size: 12px; -} - -.box:hover { - background-color: #f0f0f0; -} - -#userMap { - overflow-x: auto; - overflow-y: auto; - padding: 20px; - min-width: 770px; -} - -#userMap .active { - background-color: #d6f5d6; - border:1px solid #555; - font-weight: bold; -} - -h2.userMapTitle { - font-family: Arial; -} - -#userMap a:hover { - text-decoration: none; - } - -div.arrow { - max-width: 50px; - margin-left: 15px; - margin-right: 15px; - font-size: 20px; -} - -div.content { - max-width: 110px -} - -#userMap div.arrow, #userMap div.content { - float: left; -} - -.clearfix { - clear: both; -} - - -#userMap div.arrow { - position: relative; - top: 30px; -} - -.box1 { - margin-left:0px; -} - -button.btn.btn-default.btn-lg.modalButton1 { - margin-left: -20px; -} - -div.box.box1 { - margin-left: -20px; -} - -#userMap .btn-lg { - width: 100px; - height: 80px; - -} - -#userMap .complexArrow { - font-size: 22px; - margin: 0px 10px; -} - - -#userMap .btn-lg .active { - background-color: #d6f5d6; -} - -#userMap .btn-lg { - white-space: pre-wrap; /* css-3 */ - white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ - word-wrap: break-word; /* Internet Explorer 5.5+ */ - font-size: 14px; - } - -/* - * Let's target IE to respect aspect ratios and sizes for img tags containing SVG files - * - * [1] IE9 - * [2] IE10+ - */ -/* 1 */ -.ie9 img[src$=".svg"] { - width: 100%; -} -/* 2 */ -@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { - img[src$=".svg"] { - width: 100%; - } -} - -h4.panel-title { - padding-top: 0px; - margin-top: 0px; -} - -/*set navbar breakpoint so that it converts to hamburger earlier */ - -@media (max-width: 1200px) { - .navbar-header { - float: none; - } - .navbar-left,.navbar-right { - float: none !important; - } - .navbar-toggle { - display: block; - } - .navbar-collapse { - border-top: 1px solid transparent; - } - .navbar-fixed-top { - top: 0; - border-width: 0 0 1px; - } - .navbar-collapse.collapse { - display: none!important; - } - .navbar-nav { - float: none!important; - margin-top: 7.5px; - } - .navbar-nav>li { - float: none; - } - .navbar-nav>li>a { - padding-top: 10px; - padding-bottom: 10px; - } - .collapse.in{ - display:block !important; - } -} - -.input_area pre { - padding-bottom: 3; - margin-top: 10px; - background-color: #f5f1e0; - border: 0px; -} -.output_area pre { - padding-top: 3; - margin-top: -25px; - margin-bottom: 10px; - border: 0px; - padding-left: 2em; -} -.pytest_card { - padding: 10px 1em 4px 1em; - background-color: #eef2ff; - border-radius: 5px; - margin-bottom: 20px; -} -.pytest_card .close { - color: #000 -} -blockquote { - font-family: Menlo,Monaco,Consolas,"Courier New",monospace; -} -blockquote code { - background-color: white; -} -h4 code { - background-color: white; -} - -/* Google Custom Search styling */ - -#gcs-search-container { - width: 340px !important; /* ToDo: define width without using absolute px value */ - display: inline-block !important; -} - -.gsc-search-box.gsc-search-box-tools table { - margin-bottom: 0px !important; -} -.gsc-input, .gsc-search-button { - padding: 0; -} -.gsc-control-cse { - padding: 6px !important; -} -input.gsc-input { - font-size: 12px !important; -} diff --git a/docs/css/font-awesome.min.css b/docs/css/font-awesome.min.css deleted file mode 100644 index 0e0645d..0000000 --- a/docs/css/font-awesome.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('fonts/fontawesome-webfont.eot?v=4.7.0');src:url('fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/docs/css/fonts/FontAwesome.otf b/docs/css/fonts/FontAwesome.otf deleted file mode 100644 index 401ec0f..0000000 Binary files a/docs/css/fonts/FontAwesome.otf and /dev/null differ diff --git a/docs/css/fonts/fontawesome-webfont.eot b/docs/css/fonts/fontawesome-webfont.eot deleted file mode 100644 index e9f60ca..0000000 Binary files a/docs/css/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/docs/css/fonts/fontawesome-webfont.svg b/docs/css/fonts/fontawesome-webfont.svg deleted file mode 100644 index 855c845..0000000 --- a/docs/css/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,2671 +0,0 @@ - - - - -Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 - By ,,, -Copyright Dave Gandy 2016. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/css/fonts/fontawesome-webfont.ttf b/docs/css/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2..0000000 Binary files a/docs/css/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/docs/css/fonts/fontawesome-webfont.woff b/docs/css/fonts/fontawesome-webfont.woff deleted file mode 100644 index 400014a..0000000 Binary files a/docs/css/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/docs/css/fonts/fontawesome-webfont.woff2 b/docs/css/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc6..0000000 Binary files a/docs/css/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/docs/css/modern-business.css b/docs/css/modern-business.css deleted file mode 100755 index b0323c5..0000000 --- a/docs/css/modern-business.css +++ /dev/null @@ -1,89 +0,0 @@ -/*! - * Start Bootstrap - Modern Business HTML Template (http://startbootstrap.com) - * Code licensed under the Apache License v2.0. - * For details, see http://www.apache.org/licenses/LICENSE-2.0. - */ - -/* Global Styles */ - -html, -body { - height: 100%; -} - -.img-portfolio { - margin-bottom: 30px; -} - -.img-hover:hover { - opacity: 0.8; -} - -/* Home Page Carousel */ - -header.carousel { - height: 50%; -} - -header.carousel .item, -header.carousel .item.active, -header.carousel .carousel-inner { - height: 100%; -} - -header.carousel .fill { - width: 100%; - height: 100%; - background-position: center; - background-size: cover; -} - -/* 404 Page Styles */ - -.error-404 { - font-size: 100px; -} - -/* Pricing Page Styles */ - -.price { - display: block; - font-size: 50px; - line-height: 50px; -} - -.price sup { - top: -20px; - left: 2px; - font-size: 20px; -} - -.period { - display: block; - font-style: italic; -} - -/* Footer Styles */ - -footer { - margin: 50px 0; -} - -/* Responsive Styles */ - -@media(max-width:991px) { - .client-img, - .img-related { - margin-bottom: 30px; - } -} - -@media(max-width:767px) { - .img-portfolio { - margin-bottom: 15px; - } - - header.carousel .carousel { - height: 70%; - } -} diff --git a/docs/css/printstyles.css b/docs/css/printstyles.css deleted file mode 100644 index 64d0f63..0000000 --- a/docs/css/printstyles.css +++ /dev/null @@ -1,159 +0,0 @@ - -/*body.print .container {max-width: 650px;}*/ - -body { - font-size:14px; -} -.nav ul li a {border-top:0px; background-color:transparent; color: #808080; } -#navig a[href] {color: #595959 !important;} -table .table {max-width:650px;} - -#navig li.sectionHead {font-weight: bold; font-size: 18px; color: #595959 !important; } -#navig li {font-weight: normal; } - -#navig a[href]::after { content: leader(".") target-counter(attr(href), page); } - -a[href]::after { - content: " (page " target-counter(attr(href), page) ")" -} - -a[href^="http:"]::after, a[href^="https:"]::after { - content: ""; -} - -a[href] { - color: blue !important; -} -a[href*="mailto"]::after, a[data-toggle="tooltip"]::after, a[href].noCrossRef::after { - content: ""; -} - - -@page { - margin: 60pt 90pt 60pt 90pt; - font-family: sans-serif; - font-style:none; - color: gray; - -} - -.printTitle { - line-height:30pt; - font-size:27pt; - font-weight: bold; - letter-spacing: -.5px; - margin-bottom:25px; -} - -.printSubtitle { - font-size: 19pt; - color: #cccccc !important; - font-family: "Grotesque MT Light"; - line-height: 22pt; - letter-spacing: -.5px; - margin-bottom:20px; -} -.printTitleArea hr { - color: #999999 !important; - height: 2px; - width: 100%; -} - -.printTitleImage { - max-width:300px; - margin-bottom:200px; -} - - -.printTitleImage { - max-width: 250px; -} - -#navig { - /*page-break-before: always;*/ -} - -.copyrightBoilerplate { - page-break-before:always; - font-size:14px; -} - -.lastGeneratedDate { - font-style: italic; - font-size:14px; - color: gray; -} - -.alert a { - text-decoration: none !important; -} - - -body.title { page: title } - -@page title { - @top-left { - content: " "; - } - @top-right { - content: " " - } - @bottom-right { - content: " "; - } - @bottom-left { - content: " "; - } -} - -body.frontmatter { page: frontmatter } -body.frontmatter {counter-reset: page 1} - - -@page frontmatter { - @top-left { - content: prince-script(guideName); - } - @top-right { - content: prince-script(datestamp); - } - @bottom-right { - content: counter(page, lower-roman); - } - @bottom-left { - content: "youremail@domain.com"; } -} - -body.first_page {counter-reset: page 1} - -h1 { string-set: doctitle content() } - -@page { - @top-left { - content: string(doctitle); - font-size: 11px; - font-style: italic; - } - @top-right { - content: prince-script(datestamp); - font-size: 11px; - } - - @bottom-right { - content: "Page " counter(page); - font-size: 11px; - } - @bottom-left { - content: prince-script(guideName); - font-size: 11px; - } -} -.alert { - background-color: #fafafa !important; - border-color: #dedede !important; - color: black; -} - -pre { - background-color: #fafafa; -} diff --git a/docs/css/syntax.css b/docs/css/syntax.css deleted file mode 100644 index 1e651cf..0000000 --- a/docs/css/syntax.css +++ /dev/null @@ -1,60 +0,0 @@ -.highlight { background: #ffffff; } -.highlight .c { color: #999988; font-style: italic } /* Comment */ -.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ -.highlight .k { font-weight: bold } /* Keyword */ -.highlight .o { font-weight: bold } /* Operator */ -.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ -.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ -.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ -.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ -.highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #aa0000 } /* Generic.Error */ -.highlight .gh { color: #999999 } /* Generic.Heading */ -.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ -.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ -.highlight .go { color: #888888 } /* Generic.Output */ -.highlight .gp { color: #555555 } /* Generic.Prompt */ -.highlight .gs { font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ -.highlight .gt { color: #aa0000 } /* Generic.Traceback */ -.highlight .kc { font-weight: bold } /* Keyword.Constant */ -.highlight .kd { font-weight: bold } /* Keyword.Declaration */ -.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ -.highlight .kr { font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ -.highlight .m { color: #009999 } /* Literal.Number */ -.highlight .s { color: #d14 } /* Literal.String */ -.highlight .na { color: #008080 } /* Name.Attribute */ -.highlight .nb { color: #0086B3 } /* Name.Builtin */ -.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ -.highlight .no { color: #008080 } /* Name.Constant */ -.highlight .ni { color: #800080 } /* Name.Entity */ -.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ -.highlight .nn { color: #555555 } /* Name.Namespace */ -.highlight .nt { color: #000080 } /* Name.Tag */ -.highlight .nv { color: #008080 } /* Name.Variable */ -.highlight .ow { font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mf { color: #009999 } /* Literal.Number.Float */ -.highlight .mh { color: #009999 } /* Literal.Number.Hex */ -.highlight .mi { color: #009999 } /* Literal.Number.Integer */ -.highlight .mo { color: #009999 } /* Literal.Number.Oct */ -.highlight .sb { color: #d14 } /* Literal.String.Backtick */ -.highlight .sc { color: #d14 } /* Literal.String.Char */ -.highlight .sd { color: #d14 } /* Literal.String.Doc */ -.highlight .s2 { color: #d14 } /* Literal.String.Double */ -.highlight .se { color: #d14 } /* Literal.String.Escape */ -.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ -.highlight .si { color: #d14 } /* Literal.String.Interpol */ -.highlight .sx { color: #d14 } /* Literal.String.Other */ -.highlight .sr { color: #009926 } /* Literal.String.Regex */ -.highlight .s1 { color: #d14 } /* Literal.String.Single */ -.highlight .ss { color: #990073 } /* Literal.String.Symbol */ -.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ -.highlight .vc { color: #008080 } /* Name.Variable.Class */ -.highlight .vg { color: #008080 } /* Name.Variable.Global */ -.highlight .vi { color: #008080 } /* Name.Variable.Instance */ -.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/css/theme-blue.css b/docs/css/theme-blue.css deleted file mode 100644 index 8027c82..0000000 --- a/docs/css/theme-blue.css +++ /dev/null @@ -1,121 +0,0 @@ -.summary { - color: #808080; - border-left: 5px solid #ED1951; - font-size:16px; -} - - -h3 {color: #000000; } -h4 {color: #000000; } - -.nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus { - background-color: #248ec2; - color: white; -} - -.nav > li.active > a { - background-color: #347DBE; -} - -.nav > li > a:hover { - background-color: #248ec2; -} - -div.navbar-collapse .dropdown-menu > li > a:hover { - background-color: #347DBE; -} - -.nav li.thirdlevel > a { - background-color: #FAFAFA !important; - color: #248EC2; - font-weight: bold; -} - -a[data-toggle="tooltip"] { - color: #649345; - font-style: italic; - cursor: default; -} - -.navbar-inverse { - background-color: #347DBE; - border-color: #015CAE; -} -.navbar-inverse .navbar-nav>li>a, .navbar-inverse .navbar-brand { - color: white; -} - -.navbar-inverse .navbar-nav>li>a:hover, a.fa.fa-home.fa-lg.navbar-brand:hover { - color: #f0f0f0; -} - -a.navbar-brand:hover { - color: #f0f0f0; -} - -.navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus { - color: #015CAE; -} - -.navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus { - background-color: #015CAE; - color: #ffffff; -} - -.navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { - border-color: #248ec2 !important; -} - -.btn-primary { - color: #ffffff; - background-color: #347DBE; - border-color: #347DBE; -} - -.navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus { - background-color: #347DBE; -} - -.btn-primary:hover, -.btn-primary:focus, -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary { - background-color: #248ec2; - border-color: #347DBE; -} - -.printTitle { - color: #015CAE !important; -} - -body.print h1 {color: #015CAE !important; font-size:28px !important;} -body.print h2 {color: #595959 !important; font-size:20px !important;} -body.print h3 {color: #E50E51 !important; font-size:14px !important;} -body.print h4 {color: #679DCE !important; font-size:14px; font-style: italic !important;} - -.anchorjs-link:hover { - color: #216f9b; -} - -div.sidebarTitle { - color: #015CAE; -} - -li.sidebarTitle { - margin-top:20px; - font-weight:normal; - font-size:130%; - color: #ED1951; - margin-bottom:10px; - margin-left: 5px; - -} - -.navbar-inverse .navbar-toggle:focus, .navbar-inverse .navbar-toggle:hover { - background-color: #015CAE; -} - -.navbar-inverse .navbar-toggle { - border-color: #015CAE; -} diff --git a/docs/css/theme-green.css b/docs/css/theme-green.css deleted file mode 100644 index 4991586..0000000 --- a/docs/css/theme-green.css +++ /dev/null @@ -1,110 +0,0 @@ -.summary { - color: #808080; - border-left: 5px solid #E50E51; - font-size:16px; -} - - -h3 {color: #E50E51; } -h4 {color: #808080; } - -.nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus { - background-color: #248ec2; - color: white; -} - -.nav > li.active > a { - background-color: #72ac4a; -} - -.nav > li > a:hover { - background-color: #72ac4a; -} - -div.navbar-collapse .dropdown-menu > li > a:hover { - background-color: #72ac4a; -} - -.navbar-inverse .navbar-nav>li>a, .navbar-inverse .navbar-brand { - color: white; -} - -.navbar-inverse .navbar-nav>li>a:hover, a.fa.fa-home.fa-lg.navbar-brand:hover { - color: #f0f0f0; -} - -.nav li.thirdlevel > a { - background-color: #FAFAFA !important; - color: #72ac4a; - font-weight: bold; -} - -a[data-toggle="tooltip"] { - color: #649345; - font-style: italic; - cursor: default; -} - -.navbar-inverse { - background-color: #72ac4a; - border-color: #5b893c; -} - -.navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus { - color: #5b893c; -} - -.navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus { - background-color: #5b893c; - color: #ffffff; -} - -/* not sure if using this ...*/ -.navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { - border-color: #72ac4a !important; -} - -.btn-primary { - color: #ffffff; - background-color: #5b893c; - border-color: #5b893c; -} - -.btn-primary:hover, -.btn-primary:focus, -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary { - background-color: #72ac4a; - border-color: #5b893c; -} - -.printTitle { - color: #5b893c !important; -} - -body.print h1 {color: #5b893c !important; font-size:28px;} -body.print h2 {color: #595959 !important; font-size:24px;} -body.print h3 {color: #E50E51 !important; font-size:14px;} -body.print h4 {color: #679DCE !important; font-size:14px; font-style: italic;} - -.anchorjs-link:hover { - color: #4f7233; -} - -div.sidebarTitle { - color: #E50E51; -} - -li.sidebarTitle { - margin-top:20px; - font-weight:normal; - font-size:130%; - color: #ED1951; - margin-bottom:10px; - margin-left: 5px; -} - -.navbar-inverse .navbar-toggle:focus, .navbar-inverse .navbar-toggle:hover { - background-color: #E50E51; -} diff --git a/docs/dataframe_pipeline.html b/docs/dataframe_pipeline.html deleted file mode 100644 index 5c6b5aa..0000000 --- a/docs/dataframe_pipeline.html +++ /dev/null @@ -1,1453 +0,0 @@ ---- - -title: DataFrame PipeLine - -keywords: fastai -sidebar: home_sidebar - -summary: "A pandas dataframe pipeline" ---- - - -
- {% raw %} - -
- -
-
-
-

Dependence

This tool works on pandas DataFrame

- -
-
-
-
- -
-
-
-

Basic Structure

-
-
-
-
-
-
    -
  • [`Node`](/forgebox/dataframe_pipeline#Node) is the basic root structure of pipeline, it's a status of data
  • -
  • Edge is the change between the nodes, usually a function
  • -
- -
-
-
-
-
-

Node

    -
  • Node, works on a DataFrame
  • -
  • chunkNode, when the entire DataFrame is intimidating to the memory, a chunkNode works on a generator
  • -
- -
-
-
-
- -
-
- -
-
- -
- - -
-

class Node[source]

Node(df, verbose=1)

-
- -
- -
- -
-
- -
-
- -
-
- -
- - -
-

class chunkNode[source]

chunkNode(df_chunk, verbose=1) :: Node

-
- -
- -
- -
-
- -
-
-
-

Edges

There are 2 types of edges

- -
-
-
-
- -
-
- -
-
- -
- - -
-

class frameEdge[source]

frameEdge(edge_name=None)

-
- -
- -
- -
-
- -
-
- -
-
- -
- - -
-

class colEdge[source]

colEdge(edge_name=None)

-
- -
- -
- -
-
- -
-
- -
-
- -
- - -
-

frameEdge.define..wraper[source]

frameEdge.define..wraper(df)

-
- -
- -
- -
-
- -
-
-
-
    -
  • A frameEdge defines what happens from a dataframe to dataframe.
  • -
- -
-
-
-
-
- -
-
-
grpby = frameEdge("groupby")
-
-@grpby.define
-def grpby_func(df):
-    return df.groupby("item_id").count()
-
- -
-
-
- -
-
-
-
    -
  • A colEdge defines what happens from a column (data series) to a edited version of this column
  • -
- -
-
-
-
-
- -
-
-
double_value = colEdge("value double")
-
-@double_value.define
-def double_value_func(col):
-    return col*2
-
- -
-
-
- -
-
-
-

Some examples on edge

-
-
-
-
- -
-
- -
-
- -
- - -
-

class fillNaEdge[source]

fillNaEdge(fill=0.0) :: colEdge

-
- -
- -
- -
-
- -
-
- -
-
- -
- - -
-

class engTokEdge[source]

engTokEdge(tokenizer=None, max_len=None) :: colEdge

-
- -
- -
- -
-
- -
-
- -
-
- -
- - -
-

class CNTok[source]

CNTok() :: colEdge

-
- -
- -
- -
-
- -
-
- -
-
- -
- - -
-

class capMinMaxEdge[source]

capMinMaxEdge(min_=None, max_=None) :: colEdge

-
- -
- -
- -
-
- -
-
- -
-
- -
- - -
-

class trackVocabEdge[source]

trackVocabEdge() :: colEdge

-
-

a colEdge -input column should contain python list -This edge will keep track a vocabulary pandas DataFrame -tck_vcb = TrackVocab() -tck_vcb.vocab is the accumulated vocabulary

- -
- -
- -
-
- -
-
- -
-
- -
- - -
-

class saveCSV[source]

saveCSV(csvpath, tocsv_conf={'sep': '\t', 'index': False}) :: frameEdge

-
-

DataFrame Edge -SaveCsv("/path/to/file.csv")

- -
- -
- -
-
- -
-
- -
-
- -
- - -
-

class saveSQL[source]

saveSQL(table_name, con, tosql_conf={'index': False, 'if_exists': 'append'}) :: frameEdge

-
-

DataFrame Edge -SaveSQL("table_name", con)

- -
- -
- -
-
- -
-
-
-

Pipe in simple look

Column edges

edge defines a method of processing data.

-
    -
  • colEdge and its sub-class process column
  • -
  • frameEdge and its cub_class process a dataframe (multiple columns)
  • -
-

Nodes/Edges relationship mapping

    -
  • node1 ==edge1==> node2 :
      -
    • node2 = node1 | edge1
      -
      -
    • -
    -
  • -
  • node1 ==edge1==>edge2==> node2 :
      -
    • node2 = node1 | edge1 | edge2
      -
      -
    • -
    • node3 = node2 | edge3
      -
      -
    • -
    -
  • -
-

Relationship mapping with columns specified

    -
  • Specifying 1 column
  • -
- -
-
-
-
-
- -
-
-
node2 = node1 | edge1%"column_1"
-
- -
-
-
- -
-
-
-
    -
  • Specifying multiple columns
  • -
- -
-
-
-
-
- -
-
-
node2 = node1 | edge1*["column_2","column_3","column_4"]
-
- -
-
-
- -
-
-
-

Tutorial

-
-
-
-
-
- -
-
-
import pandas as pd
-import numpy as np
-from pathlib import Path
-import os
-
- -
-
-
- -
-
-
-

Sample dataset: New York City Airbnb Open Data

- -
-
-
-
-
- -
-
-
HOME = Path(os.environ["HOME"])/"data"
-DATA = HOME/"AB_NYC_2019.csv"
-
- -
-
-
- -
-
-
-

A preview on data set

- -
-
-
-
-
- -
-
-
df = pd.read_csv(DATA)
-
-df.head()
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
idnamehost_idhost_nameneighbourhood_groupneighbourhoodlatitudelongituderoom_typepriceminimum_nightsnumber_of_reviewslast_reviewreviews_per_monthcalculated_host_listings_countavailability_365
02539Clean & quiet apt home by the park2787JohnBrooklynKensington40.64749-73.97237Private room149192018-10-190.216365
12595Skylit Midtown Castle2845JenniferManhattanMidtown40.75362-73.98377Entire home/apt2251452019-05-210.382355
23647THE VILLAGE OF HARLEM....NEW YORK !4632ElisabethManhattanHarlem40.80902-73.94190Private room15030NaNNaN1365
33831Cozy Entire Floor of Brownstone4869LisaRoxanneBrooklynClinton Hill40.68514-73.95976Entire home/apt8912702019-07-054.641194
45022Entire Apt: Spacious Studio/Loft by central park7192LauraManhattanEast Harlem40.79851-73.94399Entire home/apt801092018-11-190.1010
-
-
- -
- -
-
- -
-
-
-

Start node, a pandas dataframe

- -
-
-
-
-
-

Real Data Example

-
-
-
-
-
- -
-
-
from forgebox.pipe import *
-
- -
-
-
- -
-
-
- -
-
-
start_node = Node(df)
-
- -
-
-
- -
-
-
- -
-
-
cap_minmax_edge = capMinMaxEdge(max_ = 100)
-fill_na_edge = fillNaEdge("")
-
- -
-
-
- -
-
-
-

Setting the node/edge pipeline

- -
-
-
-
-
- -
-
-
# clip minmax value on 1 column
-# fill na to "", on 2 columns
-# tokenize, on 2 columns
-end_node = start_node|cap_minmax_edge %"number_of_reviews"\
-                    |fill_na_edge *["name","room_type"]\
-                    |eng_twt_tk*["name","room_type"]   
-
- -
-
-
- -
-
-
-

Print out the pipeline layout

- -
-
-
-
-
- -
-
-
end_node
-
- -
-
-
- -
-
- -
- - - -
-
<forge pipeline node>
-	|cap min:None max:100
-	|fillna_
-	|En Tokenization
-
- -
- -
-
- -
-
-
-

Excute the processing

- -
-
-
-
-
- -
-
-
end_df = end_node.run()
-
- -
-
-
- -
-
- -
- -
-
[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-
-
-
- -
-
- -
-
-
-

Checking the processed data

- -
-
-
-
-
- -
-
-
end_df.head()
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
idnamehost_idhost_nameneighbourhood_groupneighbourhoodlatitudelongituderoom_typepriceminimum_nightsnumber_of_reviewslast_reviewreviews_per_monthcalculated_host_listings_countavailability_365
02539[Clean, &, quiet, apt, home, by, the, park]2787JohnBrooklynKensington40.64749-73.97237[Private, room]149192018-10-190.216365
12595[Skylit, Midtown, Castle]2845JenniferManhattanMidtown40.75362-73.98377[Entire, home, /, apt]2251452019-05-210.382355
23647[THE, VILLAGE, OF, HARLEM, ..., NEW, YORK, !]4632ElisabethManhattanHarlem40.80902-73.94190[Private, room]15030NaNNaN1365
33831[Cozy, Entire, Floor, of, Brownstone]4869LisaRoxanneBrooklynClinton Hill40.68514-73.95976[Entire, home, /, apt]8911002019-07-054.641194
45022[Entire, Apt, :, Spacious, Studio, /, Loft, by...7192LauraManhattanEast Harlem40.79851-73.94399[Entire, home, /, apt]801092018-11-190.1010
-
-
- -
- -
-
- -
-
-
-

Working with bigger data

There is often the cases when we have to deal with csv > 500m in size or a huge sql table.

-

In some cases we want to work/ save the data batch by batch

-

Gladely, pandas offer a chunksize solution, so we can process huge structured data in batch(defined by the chunk size)

- -
-
-
-
-
- -
-
-
from forgebox.pipe import chunkNode,saveCSV, saveSQL
-
- -
-
-
- -
-
-
-

[`saveCSV`](/forgebox/dataframe_pipeline#saveCSV) : saving file could be a part of the pipeline, we can follow that edge by [`saveSQL`](/forgebox/dataframe_pipeline#saveSQL) if we like

- -
-
-
-
-
- -
-
-
start_node = chunkNode(pd.read_csv(DATA, chunksize=5000), verbose = 1)
-
-end_node = start_node|cap_minmax_edge %"number_of_reviews"\
-                    |fill_na_edge *["name","room_type"]\
-                    |eng_twt_tk*["name","room_type"]\
-                    |saveCSV(HOME/"nyc_processed.csv")
-
- -
-
-
- -
-
-
-

Pipeline layout summary

- -
-
-
-
-
- -
-
-
end_node
-
- -
-
-
- -
-
- -
- - - -
-
<forge pipeline node>
-	|cap min:None max:100
-	|fillna_
-	|En Tokenization
-	|save to csv
-
- -
- -
-
- -
-
-
-

Notice

-
    -
  • run function that
      -
    • start with a chunkNode has no return,
    • -
    • start with a Node will ruturn the result dataframe.
    • -
    -
  • -
  • This feature is purposefully designed, assuming the result data could also be huge and not suitable to remain its entirety in RAM.
  • -
- -
-
-
-
-
-

Excute the processing, if you are annoyed by the verbosity, set verbose=0

- -
-
-
-
-
- -
-
-
end_node.run()
-
- -
-
-
- -
-
- -
- -
-
[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-
-
-
- -
-
- -
-
-
- -
-
-
!head -n3 {HOME/"nyc_processed.csv"}
-
- -
-
-
- -
-
- -
- -
-
0	2539	['Clean', '&', 'quiet', 'apt', 'home', 'by', 'the', 'park']	2787	John	Brooklyn	Kensington	40.647490000000005	-73.97237	['Private', 'room']	149	1	9	2018-10-19	0.21	6	365
-1	2595	['Skylit', 'Midtown', 'Castle']	2845	Jennifer	Manhattan	Midtown	40.75362	-73.98376999999999	['Entire', 'home', '/', 'apt']	225	1	45	2019-05-21	0.38	2	355
-2	3647	['THE', 'VILLAGE', 'OF', 'HARLEM', '...', 'NEW', 'YORK', '!']	4632	Elisabeth	Manhattan	Harlem	40.809020000000004	-73.9419	['Private', 'room']	150	3	0			1	365
-
-
-
- -
-
- -
-
-
-

Define a new edge

Create a new edge

-

Define the processing function with the define decorator.

-
    -
  • col is a pandas data series, the concept of column in pandas
  • -
  • In this case we use the apply function of data series, any decorated function would work as long as it return another data series
  • -
- -
-
-
-
-
- -
-
-
lower_case = colEdge("lower case")
-
-
-def lowerList(x):
-    return list(str(i).lower() for i in x)
-
-@lower_case.define
-def lower(col):
-    return col.apply(lowerList)
-
- -
-
-
- -
-
-
- -
-
-
# The DIYed edge will work on columns "name" and "room_type" after tokenization
-df = pd.read_csv(DATA)
-start_node = Node(df)
-end_node = start_node|cap_minmax_edge %"number_of_reviews"\
-                    |fill_na_edge *["name","room_type"]\
-                    |eng_twt_tk*["name","room_type"]\
-                    |lower_case*["name","room_type"]
-
- -
-
-
- -
-
-
- -
-
-
end_node
-
- -
-
-
- -
-
- -
- - - -
-
<forge pipeline node>
-	|cap min:None max:100
-	|fillna_
-	|En Tokenization
-	|lower case
-
- -
- -
-
- -
-
-
- -
-
-
end_df = end_node.run()
-end_df.head()
-
- -
-
-
- -
-
- -
- -
-
[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:lower case
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
idnamehost_idhost_nameneighbourhood_groupneighbourhoodlatitudelongituderoom_typepriceminimum_nightsnumber_of_reviewslast_reviewreviews_per_monthcalculated_host_listings_countavailability_365
02539[clean, &, quiet, apt, home, by, the, park]2787JohnBrooklynKensington40.64749-73.97237[private, room]149192018-10-190.216365
12595[skylit, midtown, castle]2845JenniferManhattanMidtown40.75362-73.98377[entire, home, /, apt]2251452019-05-210.382355
23647[the, village, of, harlem, ..., new, york, !]4632ElisabethManhattanHarlem40.80902-73.94190[private, room]15030NaNNaN1365
33831[cozy, entire, floor, of, brownstone]4869LisaRoxanneBrooklynClinton Hill40.68514-73.95976[entire, home, /, apt]8911002019-07-054.641194
45022[entire, apt, :, spacious, studio, /, loft, by...7192LauraManhattanEast Harlem40.79851-73.94399[entire, home, /, apt]801092018-11-190.1010
-
-
- -
- -
-
- -
- {% endraw %} -
- - diff --git a/docs/df.html b/docs/df.html deleted file mode 100644 index f9be1f8..0000000 --- a/docs/df.html +++ /dev/null @@ -1,289 +0,0 @@ ---- - -title: Tools on pandas dataframe - -keywords: fastai -sidebar: home_sidebar - -summary: "Shortcuts tools on pandas dataframe" ---- - - -
- {% raw %} - -
- -
-
- -
-
- -
-
- -
- - -
-

class PandasDisplay[source]

PandasDisplay(**kwargs)

-
-

Temporary pandas display config "with" hook -with PandasDisplay(max_colwidth = 0,max_rows=100): - display(df)

- -
- -
- -
-
- -
-
-
- -
-
-
# let's say we have a pretty long piece of text with in pandas dataframe
-df_example = pd.DataFrame({"text":["""To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me, and hindered me half a million; laughed at my losses, mocked at my gains, scorned my nation, thwarted my bargains, cooled my friends, heated mine enemies; and what's his reason? I am a Jew. Hath not a Jew eyes? hath not a Jew hands, organs, dimensions, senses, affections, passions? fed with the same food, hurt with the same weapons, subject to the same diseases, healed by the same means, warmed and cooled by the same winter and summer, as a Christian is? If you prick us, do we not bleed? if you tickle us, do we not laugh? if you poison us, do we not die? and if you wrong us, shall we not revenge? If we are like you in the rest, we will resemble you in that. If a Jew wrong a Christian, what is his humility? Revenge. If a Christian wrong a Jew, what should his sufferance be by Christian example? Why, revenge. The villany you teach me, I will execute, and it shall go hard but I will better the instruction.""",]*10})
-
-pd.set_option("display.max_colwidth",100)
-pd.set_option("display.max_rows",2)
-
- -
-
-
- -
-
-
-

Such long text usually won't display in full length at usual pandas config, and we can see some rows are concluded, too

- -
-
-
-
-
- -
-
-
# display the dataframe use the original config
-display(df_example)
-
-# display the dataframe use the temporary config
-print("=>use new config")
-with PandasDisplay(max_colwidth = 0,max_rows = 10):
-    display(df_example)
-
-# display the dataframe use the original config
-print("=>going back to original config")
-display(df_example)
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - -
text
0To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me...
......
9To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me...
-

10 rows × 1 columns

-
-
- -
- -
- -
-
=>use new config
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
text
0To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me, and hindered me half a million; laughed at my losses, mocked at my gains, scorned my nation, thwarted my bargains, cooled my friends, heated mine enemies; and what's his reason? I am a Jew. Hath not a Jew eyes? hath not a Jew hands, organs, dimensions, senses, affections, passions? fed with the same food, hurt with the same weapons, subject to the same diseases, healed by the same means, warmed and cooled by the same winter and summer, as a Christian is? If you prick us, do we not bleed? if you tickle us, do we not laugh? if you poison us, do we not die? and if you wrong us, shall we not revenge? If we are like you in the rest, we will resemble you in that. If a Jew wrong a Christian, what is his humility? Revenge. If a Christian wrong a Jew, what should his sufferance be by Christian example? Why, revenge. The villany you teach me, I will execute, and it shall go hard but I will better the instruction.
1To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me, and hindered me half a million; laughed at my losses, mocked at my gains, scorned my nation, thwarted my bargains, cooled my friends, heated mine enemies; and what's his reason? I am a Jew. Hath not a Jew eyes? hath not a Jew hands, organs, dimensions, senses, affections, passions? fed with the same food, hurt with the same weapons, subject to the same diseases, healed by the same means, warmed and cooled by the same winter and summer, as a Christian is? If you prick us, do we not bleed? if you tickle us, do we not laugh? if you poison us, do we not die? and if you wrong us, shall we not revenge? If we are like you in the rest, we will resemble you in that. If a Jew wrong a Christian, what is his humility? Revenge. If a Christian wrong a Jew, what should his sufferance be by Christian example? Why, revenge. The villany you teach me, I will execute, and it shall go hard but I will better the instruction.
2To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me, and hindered me half a million; laughed at my losses, mocked at my gains, scorned my nation, thwarted my bargains, cooled my friends, heated mine enemies; and what's his reason? I am a Jew. Hath not a Jew eyes? hath not a Jew hands, organs, dimensions, senses, affections, passions? fed with the same food, hurt with the same weapons, subject to the same diseases, healed by the same means, warmed and cooled by the same winter and summer, as a Christian is? If you prick us, do we not bleed? if you tickle us, do we not laugh? if you poison us, do we not die? and if you wrong us, shall we not revenge? If we are like you in the rest, we will resemble you in that. If a Jew wrong a Christian, what is his humility? Revenge. If a Christian wrong a Jew, what should his sufferance be by Christian example? Why, revenge. The villany you teach me, I will execute, and it shall go hard but I will better the instruction.
3To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me, and hindered me half a million; laughed at my losses, mocked at my gains, scorned my nation, thwarted my bargains, cooled my friends, heated mine enemies; and what's his reason? I am a Jew. Hath not a Jew eyes? hath not a Jew hands, organs, dimensions, senses, affections, passions? fed with the same food, hurt with the same weapons, subject to the same diseases, healed by the same means, warmed and cooled by the same winter and summer, as a Christian is? If you prick us, do we not bleed? if you tickle us, do we not laugh? if you poison us, do we not die? and if you wrong us, shall we not revenge? If we are like you in the rest, we will resemble you in that. If a Jew wrong a Christian, what is his humility? Revenge. If a Christian wrong a Jew, what should his sufferance be by Christian example? Why, revenge. The villany you teach me, I will execute, and it shall go hard but I will better the instruction.
4To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me, and hindered me half a million; laughed at my losses, mocked at my gains, scorned my nation, thwarted my bargains, cooled my friends, heated mine enemies; and what's his reason? I am a Jew. Hath not a Jew eyes? hath not a Jew hands, organs, dimensions, senses, affections, passions? fed with the same food, hurt with the same weapons, subject to the same diseases, healed by the same means, warmed and cooled by the same winter and summer, as a Christian is? If you prick us, do we not bleed? if you tickle us, do we not laugh? if you poison us, do we not die? and if you wrong us, shall we not revenge? If we are like you in the rest, we will resemble you in that. If a Jew wrong a Christian, what is his humility? Revenge. If a Christian wrong a Jew, what should his sufferance be by Christian example? Why, revenge. The villany you teach me, I will execute, and it shall go hard but I will better the instruction.
5To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me, and hindered me half a million; laughed at my losses, mocked at my gains, scorned my nation, thwarted my bargains, cooled my friends, heated mine enemies; and what's his reason? I am a Jew. Hath not a Jew eyes? hath not a Jew hands, organs, dimensions, senses, affections, passions? fed with the same food, hurt with the same weapons, subject to the same diseases, healed by the same means, warmed and cooled by the same winter and summer, as a Christian is? If you prick us, do we not bleed? if you tickle us, do we not laugh? if you poison us, do we not die? and if you wrong us, shall we not revenge? If we are like you in the rest, we will resemble you in that. If a Jew wrong a Christian, what is his humility? Revenge. If a Christian wrong a Jew, what should his sufferance be by Christian example? Why, revenge. The villany you teach me, I will execute, and it shall go hard but I will better the instruction.
6To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me, and hindered me half a million; laughed at my losses, mocked at my gains, scorned my nation, thwarted my bargains, cooled my friends, heated mine enemies; and what's his reason? I am a Jew. Hath not a Jew eyes? hath not a Jew hands, organs, dimensions, senses, affections, passions? fed with the same food, hurt with the same weapons, subject to the same diseases, healed by the same means, warmed and cooled by the same winter and summer, as a Christian is? If you prick us, do we not bleed? if you tickle us, do we not laugh? if you poison us, do we not die? and if you wrong us, shall we not revenge? If we are like you in the rest, we will resemble you in that. If a Jew wrong a Christian, what is his humility? Revenge. If a Christian wrong a Jew, what should his sufferance be by Christian example? Why, revenge. The villany you teach me, I will execute, and it shall go hard but I will better the instruction.
7To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me, and hindered me half a million; laughed at my losses, mocked at my gains, scorned my nation, thwarted my bargains, cooled my friends, heated mine enemies; and what's his reason? I am a Jew. Hath not a Jew eyes? hath not a Jew hands, organs, dimensions, senses, affections, passions? fed with the same food, hurt with the same weapons, subject to the same diseases, healed by the same means, warmed and cooled by the same winter and summer, as a Christian is? If you prick us, do we not bleed? if you tickle us, do we not laugh? if you poison us, do we not die? and if you wrong us, shall we not revenge? If we are like you in the rest, we will resemble you in that. If a Jew wrong a Christian, what is his humility? Revenge. If a Christian wrong a Jew, what should his sufferance be by Christian example? Why, revenge. The villany you teach me, I will execute, and it shall go hard but I will better the instruction.
8To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me, and hindered me half a million; laughed at my losses, mocked at my gains, scorned my nation, thwarted my bargains, cooled my friends, heated mine enemies; and what's his reason? I am a Jew. Hath not a Jew eyes? hath not a Jew hands, organs, dimensions, senses, affections, passions? fed with the same food, hurt with the same weapons, subject to the same diseases, healed by the same means, warmed and cooled by the same winter and summer, as a Christian is? If you prick us, do we not bleed? if you tickle us, do we not laugh? if you poison us, do we not die? and if you wrong us, shall we not revenge? If we are like you in the rest, we will resemble you in that. If a Jew wrong a Christian, what is his humility? Revenge. If a Christian wrong a Jew, what should his sufferance be by Christian example? Why, revenge. The villany you teach me, I will execute, and it shall go hard but I will better the instruction.
9To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me, and hindered me half a million; laughed at my losses, mocked at my gains, scorned my nation, thwarted my bargains, cooled my friends, heated mine enemies; and what's his reason? I am a Jew. Hath not a Jew eyes? hath not a Jew hands, organs, dimensions, senses, affections, passions? fed with the same food, hurt with the same weapons, subject to the same diseases, healed by the same means, warmed and cooled by the same winter and summer, as a Christian is? If you prick us, do we not bleed? if you tickle us, do we not laugh? if you poison us, do we not die? and if you wrong us, shall we not revenge? If we are like you in the rest, we will resemble you in that. If a Jew wrong a Christian, what is his humility? Revenge. If a Christian wrong a Jew, what should his sufferance be by Christian example? Why, revenge. The villany you teach me, I will execute, and it shall go hard but I will better the instruction.
-
-
- -
- -
- -
-
=>going back to original config
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - -
text
0To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me...
......
9To bait fish withal: if it will feed nothing else, it will feed my revenge. He hath disgraced me...
-

10 rows × 1 columns

-
-
- -
- -
-
- -
- {% endraw %} -
- - diff --git a/docs/df_filter.html b/docs/df_filter.html deleted file mode 100644 index 9ac68c0..0000000 --- a/docs/df_filter.html +++ /dev/null @@ -1,1183 +0,0 @@ ---- - -title: Dataframe filter - - -keywords: fastai -sidebar: home_sidebar - -summary: "Simple dataframe filter, Interactivel y filter column by value, one by one" -description: "Simple dataframe filter, Interactivel y filter column by value, one by one" -nb_path: "nbs/31_df_filter.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
def get_cal_housing():
-    from sklearn.datasets import california_housing
-    data = california_housing.fetch_california_housing()
-    df = pd.DataFrame(data['data'], columns=data['feature_names'])
-    return df
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df = get_cal_housing()
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MedIncHouseAgeAveRoomsAveBedrmsPopulationAveOccupLatitudeLongitude
08.325241.06.9841271.023810322.02.55555637.88-122.23
18.301421.06.2381370.9718802401.02.10984237.86-122.22
27.257452.08.2881361.073446496.02.80226037.85-122.24
35.643152.05.8173521.073059558.02.54794537.85-122.25
43.846252.06.2818531.081081565.02.18146737.85-122.25
...........................
206351.560325.05.0454551.133333845.02.56060639.48-121.09
206362.556818.06.1140351.315789356.03.12280739.49-121.21
206371.700017.05.2055431.1200921007.02.32563539.43-121.22
206381.867218.05.3295131.171920741.02.12320939.43-121.32
206392.388616.05.2547171.1622641387.02.61698139.37-121.24
-

20640 rows × 8 columns

-
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
"32.8%">"35.2%", "32.8%">"15.2%"
-
- -
-
-
- -
-
- -
- - - -
-
(False, True)
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MedIncHouseAgeAveRoomsAveBedrmsPopulationAveOccupLatitudeLongitudeTestPercent
08.325241.06.9841271.023810322.02.55555637.88-122.2388.91410755185981%
18.301421.06.2381370.9718802401.02.10984237.86-122.2293.83564895188734%
27.257452.08.2881361.073446496.02.80226037.85-122.2470.91076297605066%
35.643152.05.8173521.073059558.02.54794537.85-122.2521.56618642530764%
43.846252.06.2818531.081081565.02.18146737.85-122.2580.45282896672339%
..............................
206351.560325.05.0454551.133333845.02.56060639.48-121.0936.93266496322409%
206362.556818.06.1140351.315789356.03.12280739.49-121.2175.0362361985378%
206371.700017.05.2055431.1200921007.02.32563539.43-121.2278.31525111633049%
206381.867218.05.3295131.171920741.02.12320939.43-121.3246.47093977393043%
206392.388616.05.2547171.1622641387.02.61698139.37-121.2442.4080878652766%
-

20640 rows × 9 columns

-
-
- -
- -
-
- -
- {% endraw %} - -
-
-

A tool to filter data

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

pct_to_float[source]

pct_to_float(x)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

ensure_pct[source]

ensure_pct(df)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

detect_number_column[source]

detect_number_column(df)

-
-

Detect number columns in dataframe

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

class DataFilter[source]

DataFilter(df:DataFrame, fix_pct=True)

-
-

Single column number filter

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MedIncHouseAgeAveRoomsAveBedrmsPopulationAveOccupLatitudeLongitudeTestPercent
08.325241.06.9841271.023810322.02.55555637.88-122.2388.91410755185981%
18.301421.06.2381370.9718802401.02.10984237.86-122.2293.83564895188734%
27.257452.08.2881361.073446496.02.80226037.85-122.2470.91076297605066%
35.643152.05.8173521.073059558.02.54794537.85-122.2521.56618642530764%
43.846252.06.2818531.081081565.02.18146737.85-122.2580.45282896672339%
..............................
206351.560325.05.0454551.133333845.02.56060639.48-121.0936.93266496322409%
206362.556818.06.1140351.315789356.03.12280739.49-121.2175.0362361985378%
206371.700017.05.2055431.1200921007.02.32563539.43-121.2278.31525111633049%
206381.867218.05.3295131.171920741.02.12320939.43-121.3246.47093977393043%
206392.388616.05.2547171.1622641387.02.61698139.37-121.2442.4080878652766%
-

20640 rows × 9 columns

-
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
data_filter = DataFilter(df)
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
data_filter(columns=["AveBedrms", "Latitude", "TestPercent"])
-
- -
-
-
- -
- {% endraw %} - -
-
-

Extract out the dataframe afterwards

-
-
-
- {% raw %} - -
-
- -
-
-
data_filter.df
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MedIncHouseAgeAveRoomsAveBedrmsPopulationAveOccupLatitudeLongitude
08.325241.06.9841271.023810322.02.55555637.88-122.23
18.301421.06.2381370.9718802401.02.10984237.86-122.22
27.257452.08.2881361.073446496.02.80226037.85-122.24
35.643152.05.8173521.073059558.02.54794537.85-122.25
43.846252.06.2818531.081081565.02.18146737.85-122.25
...........................
206351.560325.05.0454551.133333845.02.56060639.48-121.09
206362.556818.06.1140351.315789356.03.12280739.49-121.21
206371.700017.05.2055431.1200921007.02.32563539.43-121.22
206381.867218.05.3295131.171920741.02.12320939.43-121.32
206392.388616.05.2547171.1622641387.02.61698139.37-121.24
-

20640 rows × 8 columns

-
-
- -
- -
-
- -
- {% endraw %} - -
-
-

RecursiveFilter

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

class LayerTorch[source]

LayerTorch(df, level=0, last_layer=None)

-
-

information passon from layer to layer

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

class RecursiveFilterCore[source]

RecursiveFilterCore() :: ABC

-
-

Helper class that provides a standard way to create an ABC using -inheritance.

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

class RecursiveFilter[source]

RecursiveFilter(data=None, index:Axes | None=None, columns:Axes | None=None, dtype:Dtype | None=None, copy:bool | None=None) :: DataFrame

-
-

Interactive Pandas DataFrame Filter -df = RecursiveFilter(df) -df.handpick()

- -
Hand pick the portion of the data frame you liked
-    from filtering the column by value.
-A function from enhanced pandas dataframe
-
-Inputs:
-- chunk_callbacks: List[Callable]=[],
-- show_top: bool, default True, do we should
-    the most frequent values of the current column
-- show_top_k: int, the number of rows we show for
-    the most frequent values, when show_top=True,
-    default 20
-- pick_value_top_k: int, number of the most frequent
-    values in pick drop down default 30
-- from_last_layer: LayerTorch, default None, this
-    column doesn't mean for user configuration
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df = RecursiveFilter(df)
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df.handpick()
-
- -
-
-
- -
-
- -
- -
-
/Users/xiaochen.zhang/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:15: UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html#attribute-access
-  from ipykernel import kernelapp as app
-
-
-
- -
-
- -
- {% endraw %} - -
- - diff --git a/docs/etl.html b/docs/etl.html deleted file mode 100644 index cf220fe..0000000 --- a/docs/etl.html +++ /dev/null @@ -1,124 +0,0 @@ ---- - -title: ETL Helper - - -keywords: fastai -sidebar: home_sidebar - -summary: "A combined ETL tool sets" -description: "A combined ETL tool sets" -nb_path: "nbs/11_etl.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - -
-
-

A list for each step

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

class NewFileScanner[source]

NewFileScanner(directory, new_file_filter:Callable=None, done_list_getter:Callable=None, stop_callback:Callable=None)

-
-

Keep scannning a directory for new file -if found any, callback processing the file

-

Designed for download and delete strategy

-

Example

new_file_scanner = NewFileScanner(".", new_file_filter=lambda x:x[-4:]==".txt") -new_file_scanner(lambda x:print(f"new file:{x} found"))s

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Test new file scanner

-
-
-
- {% raw %} - -
-
- -
-
-
new_file_scanner = NewFileScanner(".", new_file_filter=lambda x:x[-4:]==".txt")
-new_file_scanner(lambda x:print(f"new file:{x} found"))
-
- -
-
-
- -
-
- -
- -
-
new file:untitled.txt found
-new file:bc.txt found
-new file:cde.txt found
-
-
-
- -
- -
-
ERROR:root:manually stoped
-
-
-
- -
-
- -
- {% endraw %} - -
- - diff --git a/docs/feed.xml b/docs/feed.xml deleted file mode 100644 index d8d6ac9..0000000 --- a/docs/feed.xml +++ /dev/null @@ -1,32 +0,0 @@ ---- -search: exclude -layout: none ---- - - - - - {{ site.title | xml_escape }} - {{ site.description | xml_escape }} - {{ site.url }}/ - - {{ site.time | date_to_rfc822 }} - {{ site.time | date_to_rfc822 }} - Jekyll v{{ jekyll.version }} - {% for post in site.posts limit:10 %} - - {{ post.title | xml_escape }} - {{ post.content | xml_escape }} - {{ post.date | date_to_rfc822 }} - {{ post.url | prepend: site.url }} - {{ post.url | prepend: site.url }} - {% for tag in post.tags %} - {{ tag | xml_escape }} - {% endfor %} - {% for tag in page.tags %} - {{ cat | xml_escape }} - {% endfor %} - - {% endfor %} - - diff --git a/docs/files.html b/docs/files.html deleted file mode 100644 index aa13777..0000000 --- a/docs/files.html +++ /dev/null @@ -1,241 +0,0 @@ ---- - -title: Hard drive files - - -keywords: fastai -sidebar: home_sidebar - -summary: "Extract information on files under a directory" -description: "Extract information on files under a directory" -nb_path: "nbs/33_files.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

get_files[source]

get_files(path:Path, skip:Union[str, List[str]]=None)

-
-

Get all file paths from a directory

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

file_detail[source]

file_detail(path:Path, skip:Union[str, List[str]]=None)

-
-

Get detailed file information from a directory

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
file_detail("../../../Downloads/apiGateway-js-sdk")
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pathfile_typeparentdepth
0/Users/xiaochen.zhang/github/forgebox/nbs/../....DS_StoreapiGateway-js-sdk12
1/Users/xiaochen.zhang/github/forgebox/nbs/../....mdapiGateway-js-sdk12
2/Users/xiaochen.zhang/github/forgebox/nbs/../....jsapiGateway-js-sdk12
3/Users/xiaochen.zhang/github/forgebox/nbs/../....jscomponents15
4/Users/xiaochen.zhang/github/forgebox/nbs/../....jscomponents15
5/Users/xiaochen.zhang/github/forgebox/nbs/../....jsrollups15
6/Users/xiaochen.zhang/github/forgebox/nbs/../....jsrollups15
7/Users/xiaochen.zhang/github/forgebox/nbs/../....jsurl-template14
8/Users/xiaochen.zhang/github/forgebox/nbs/../....jsapiGatewayCore14
9/Users/xiaochen.zhang/github/forgebox/nbs/../....jsapiGatewayCore14
10/Users/xiaochen.zhang/github/forgebox/nbs/../....jsapiGatewayCore14
11/Users/xiaochen.zhang/github/forgebox/nbs/../....jsapiGatewayCore14
12/Users/xiaochen.zhang/github/forgebox/nbs/../....jsdist15
-
-
- -
- -
-
- -
- {% endraw %} - -
- - diff --git a/docs/flatten.html b/docs/flatten.html deleted file mode 100644 index 61bccf0..0000000 --- a/docs/flatten.html +++ /dev/null @@ -1,111 +0,0 @@ ---- - -title: Flatten - - -keywords: fastai -sidebar: home_sidebar - - - -nb_path: "nbs/06_flatten.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - -
-
-

Flattening the tree structure

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

class Flatten[source]

Flatten(data, key_callback:Callable=None, key_connection:str='_')

-
-

Flatten a tree structure dictionary

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Testing a tree structure

-
-
-
- {% raw %} - -
-
- -
-
-
Flatten({"a":[1,2,{"c":"d"}],"b":{"g":1}}, key_connection="=>")()
-
- -
-
-
- -
-
- -
- - - -
-
{'a': [1, 2, {'c': 'd'}], 'b=>g': 1}
-
- -
- -
-
- -
- {% endraw %} - -
- - diff --git a/docs/fonts/FontAwesome.otf b/docs/fonts/FontAwesome.otf deleted file mode 100644 index 81c9ad9..0000000 Binary files a/docs/fonts/FontAwesome.otf and /dev/null differ diff --git a/docs/fonts/fontawesome-webfont.eot b/docs/fonts/fontawesome-webfont.eot deleted file mode 100644 index 84677bc..0000000 Binary files a/docs/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/docs/fonts/fontawesome-webfont.svg b/docs/fonts/fontawesome-webfont.svg deleted file mode 100644 index d907b25..0000000 --- a/docs/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,520 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/fonts/fontawesome-webfont.ttf b/docs/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 96a3639..0000000 Binary files a/docs/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/docs/fonts/fontawesome-webfont.woff b/docs/fonts/fontawesome-webfont.woff deleted file mode 100644 index 628b6a5..0000000 Binary files a/docs/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/docs/fonts/glyphicons-halflings-regular.eot b/docs/fonts/glyphicons-halflings-regular.eot deleted file mode 100644 index b93a495..0000000 Binary files a/docs/fonts/glyphicons-halflings-regular.eot and /dev/null differ diff --git a/docs/fonts/glyphicons-halflings-regular.svg b/docs/fonts/glyphicons-halflings-regular.svg deleted file mode 100644 index 94fb549..0000000 --- a/docs/fonts/glyphicons-halflings-regular.svg +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/fonts/glyphicons-halflings-regular.ttf b/docs/fonts/glyphicons-halflings-regular.ttf deleted file mode 100644 index 1413fc6..0000000 Binary files a/docs/fonts/glyphicons-halflings-regular.ttf and /dev/null differ diff --git a/docs/fonts/glyphicons-halflings-regular.woff b/docs/fonts/glyphicons-halflings-regular.woff deleted file mode 100644 index 9e61285..0000000 Binary files a/docs/fonts/glyphicons-halflings-regular.woff and /dev/null differ diff --git a/docs/fonts/glyphicons-halflings-regular.woff2 b/docs/fonts/glyphicons-halflings-regular.woff2 deleted file mode 100644 index 64539b5..0000000 Binary files a/docs/fonts/glyphicons-halflings-regular.woff2 and /dev/null differ diff --git a/docs/forgebox_test.html b/docs/forgebox_test.html deleted file mode 100644 index 7f8d910..0000000 --- a/docs/forgebox_test.html +++ /dev/null @@ -1,1078 +0,0 @@ ---- - -title: Title - -keywords: fastai -sidebar: home_sidebar - -summary: "summary" ---- - - -
- {% raw %} - -
- -
-
-
-

FrogeBox Pipe

A pandas dataframe pipeline

This is a tutorial about tabular data processing pipeline

- -
-
-
-
-
- -
-
-
import pandas as pd
-import numpy as np
-from pathlib import Path
-import os
-
- -
-
-
- -
-
-
-

Sample dataset: New York City Airbnb Open Data

- -
-
-
-
-
- -
-
-
HOME = Path(os.environ["HOME"])/"data"
-DATA = HOME/"AB_NYC_2019.csv"
-
- -
-
-
- -
-
-
-

A preview on data set

- -
-
-
-
-
- -
-
-
df = pd.read_csv(DATA)
-
-df.head()
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
idnamehost_idhost_nameneighbourhood_groupneighbourhoodlatitudelongituderoom_typepriceminimum_nightsnumber_of_reviewslast_reviewreviews_per_monthcalculated_host_listings_countavailability_365
02539Clean & quiet apt home by the park2787JohnBrooklynKensington40.64749-73.97237Private room149192018-10-190.216365
12595Skylit Midtown Castle2845JenniferManhattanMidtown40.75362-73.98377Entire home/apt2251452019-05-210.382355
23647THE VILLAGE OF HARLEM....NEW YORK !4632ElisabethManhattanHarlem40.80902-73.94190Private room15030NaNNaN1365
33831Cozy Entire Floor of Brownstone4869LisaRoxanneBrooklynClinton Hill40.68514-73.95976Entire home/apt8912702019-07-054.641194
45022Entire Apt: Spacious Studio/Loft by central park7192LauraManhattanEast Harlem40.79851-73.94399Entire home/apt801092018-11-190.1010
-
-
- -
- -
-
- -
-
-
-

DataFrame Pipeline

-
-
-
-
-
- -
-
-
from forgebox.pipe import Node,colEdge
-from forgebox.pipe.edge import capMinMaxEdge,eng_twt_tk,fillNaEdge
-
- -
-
-
- -
-
-
-

Start node, a pandas dataframe

- -
-
-
-
-
- -
-
-
start_node = Node(df)
-
- -
-
-
- -
-
-
-

Column edges

edge defines a method of processing data.

-
    -
  • colEdge and its sub-class process column
  • -
  • frameEdge and its cub_class process a dataframe (multiple columns)
  • -
- -
-
-
-
-
- -
-
-
cap_minmax_edge = capMinMaxEdge(max_ = 100)
-fill_na_edge = fillNaEdge("")
-
- -
-
-
- -
-
-
-

Nodes/Edges relationship mapping

    -
  • node1 ==edge1==> node2 :
      -
    • node2 = node1 | edge1
      -
      -
    • -
    -
  • -
  • node1 ==edge1==>edge2==> node2 :
      -
    • node2 = node1 | edge1 | edge2
      -
      -
    • -
    • node3 = node2 | edge3
      -
      -
    • -
    -
  • -
-

Relationship mapping with columns specified

    -
  • Specifying 1 column
      -
    • node2 = node1 | edge1%"column_1"
      -
      -
    • -
    -
  • -
  • Specifying multiple columns
      -
    • node2 = node1 | edge1*["column_2","column_3","column_4"]
      -
      -
    • -
    -
  • -
- -
-
-
-
-
-

Setting the node/edge pipeline

- -
-
-
-
-
- -
-
-
# clip minmax value on 1 column
-# fill na to "", on 2 columns
-# tokenize, on 2 columns
-end_node = start_node|cap_minmax_edge %"number_of_reviews"\
-                    |fill_na_edge *["name","room_type"]\
-                    |eng_twt_tk*["name","room_type"]   
-
- -
-
-
- -
-
-
-

Print out the pipeline layout

- -
-
-
-
-
- -
-
-
end_node
-
- -
-
-
- -
-
- -
- - - -
-
<forge pipeline node>
-	|cap min:None max:100
-	|fillna_
-	|En Tokenization
-
- -
- -
-
- -
-
-
-

Excute the processing

- -
-
-
-
-
- -
-
-
end_df = end_node.run()
-
- -
-
-
- -
-
- -
- -
-
[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-
-
-
- -
-
- -
-
-
-

Checking the processed data

- -
-
-
-
-
- -
-
-
end_df.head()
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
idnamehost_idhost_nameneighbourhood_groupneighbourhoodlatitudelongituderoom_typepriceminimum_nightsnumber_of_reviewslast_reviewreviews_per_monthcalculated_host_listings_countavailability_365
02539[Clean, &, quiet, apt, home, by, the, park]2787JohnBrooklynKensington40.64749-73.97237[Private, room]149192018-10-190.216365
12595[Skylit, Midtown, Castle]2845JenniferManhattanMidtown40.75362-73.98377[Entire, home, /, apt]2251452019-05-210.382355
23647[THE, VILLAGE, OF, HARLEM, ..., NEW, YORK, !]4632ElisabethManhattanHarlem40.80902-73.94190[Private, room]15030NaNNaN1365
33831[Cozy, Entire, Floor, of, Brownstone]4869LisaRoxanneBrooklynClinton Hill40.68514-73.95976[Entire, home, /, apt]8911002019-07-054.641194
45022[Entire, Apt, :, Spacious, Studio, /, Loft, by...7192LauraManhattanEast Harlem40.79851-73.94399[Entire, home, /, apt]801092018-11-190.1010
-
-
- -
- -
-
- -
-
-
-

Working with bigger data

There is often the cases when we have to deal with csv > 500m in size or a huge sql table.

-

Gladely, pandas offer a chunksize solution, so we can process huge structured data in batch(defined by the chunk size)

- -
-
-
-
-
- -
-
-
from forgebox.pipe import chunkNode
-from forgebox.pipe.edge import saveCSV, saveSQL
-
- -
-
-
- -
-
-
-

saveCSV : saving file could be a part of the pipeline, we can follow that edge by saveSQL if we like

- -
-
-
-
-
- -
-
-
start_node = chunkNode(pd.read_csv(DATA, chunksize=5000), verbose = 1)
-
-end_node = start_node|cap_minmax_edge %"number_of_reviews"\
-                    |fill_na_edge *["name","room_type"]\
-                    |eng_twt_tk*["name","room_type"]\
-                    |saveCSV(HOME/"nyc_processed.csv")
-
- -
-
-
- -
-
-
-

Pipeline layout summary

- -
-
-
-
-
- -
-
-
end_node
-
- -
-
-
- -
-
- -
- - - -
-
<forge pipeline node>
-	|cap min:None max:100
-	|fillna_
-	|En Tokenization
-	|save to csv
-
- -
- -
-
- -
-
-
-

Notice

-
    -
  • run function that
      -
    • start with a chunkNode has no return,
    • -
    • start with a Node will ruturn the result dataframe.
    • -
    -
  • -
  • This feature is purposefully designed, assuming the result data could also be huge and not suitable to remain its entirety in RAM.
  • -
- -
-
-
-
-
-

Excute the processing, if you are annoyed by the verbosity, set verbose=0

- -
-
-
-
-
- -
-
-
end_node.run()
-
- -
-
-
- -
-
- -
- -
-
[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:save to csv
-
-
-
- -
-
- -
-
-
- -
-
-
!head -n3 {HOME/"nyc_processed.csv"}
-
- -
-
-
- -
-
- -
- -
-
0	2539	['Clean', '&', 'quiet', 'apt', 'home', 'by', 'the', 'park']	2787	John	Brooklyn	Kensington	40.647490000000005	-73.97237	['Private', 'room']	149	1	9	2018-10-19	0.21	6	365
-1	2595	['Skylit', 'Midtown', 'Castle']	2845	Jennifer	Manhattan	Midtown	40.75362	-73.98376999999999	['Entire', 'home', '/', 'apt']	225	1	45	2019-05-21	0.38	2	355
-2	3647	['THE', 'VILLAGE', 'OF', 'HARLEM', '...', 'NEW', 'YORK', '!']	4632	Elisabeth	Manhattan	Harlem	40.809020000000004	-73.9419	['Private', 'room']	150	3	0			1	365
-
-
-
- -
-
- -
-
-
-

Define a new edge

Create a new edge

-

Define the processing function with the define decorator.

-
    -
  • col is a pandas data series, the concept of column in pandas
  • -
  • In this case we use the apply function of data series, any decorated function would work as long as it return another data series
  • -
- -
-
-
-
-
- -
-
-
lower_case = colEdge("lower case")
-
-
-def lowerList(x):
-    return list(str(i).lower() for i in x)
-
-@lower_case.define
-def lower(col):
-    return col.apply(lowerList)
-
- -
-
-
- -
-
-
- -
-
-
# The DIYed edge will work on columns "name" and "room_type" after tokenization
-df = pd.read_csv(DATA)
-start_node = Node(df)
-end_node = start_node|cap_minmax_edge %"number_of_reviews"\
-                    |fill_na_edge *["name","room_type"]\
-                    |eng_twt_tk*["name","room_type"]\
-                    |lower_case*["name","room_type"]
-
- -
-
-
- -
-
-
- -
-
-
end_node
-
- -
-
-
- -
-
- -
- - - -
-
<forge pipeline node>
-	|cap min:None max:100
-	|fillna_
-	|En Tokenization
-	|lower case
-
- -
- -
-
- -
-
-
- -
-
-
end_df = end_node.run()
-end_df.head()
-
- -
-
-
- -
-
- -
- -
-
[df edge]:cap min:None max:100
-[df edge]:fillna_
-[df edge]:En Tokenization
-[df edge]:lower case
-
-
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
idnamehost_idhost_nameneighbourhood_groupneighbourhoodlatitudelongituderoom_typepriceminimum_nightsnumber_of_reviewslast_reviewreviews_per_monthcalculated_host_listings_countavailability_365
02539[clean, &, quiet, apt, home, by, the, park]2787JohnBrooklynKensington40.64749-73.97237[private, room]149192018-10-190.216365
12595[skylit, midtown, castle]2845JenniferManhattanMidtown40.75362-73.98377[entire, home, /, apt]2251452019-05-210.382355
23647[the, village, of, harlem, ..., new, york, !]4632ElisabethManhattanHarlem40.80902-73.94190[private, room]15030NaNNaN1365
33831[cozy, entire, floor, of, brownstone]4869LisaRoxanneBrooklynClinton Hill40.68514-73.95976[entire, home, /, apt]8911002019-07-054.641194
45022[entire, apt, :, spacious, studio, /, loft, by...7192LauraManhattanEast Harlem40.79851-73.94399[entire, home, /, apt]801092018-11-190.1010
-
-
- -
- -
-
- -
- {% endraw %} -
- - diff --git a/docs/freemap.html b/docs/freemap.html deleted file mode 100644 index 1e82e3c..0000000 --- a/docs/freemap.html +++ /dev/null @@ -1,259 +0,0 @@ ---- - -title: FreeMap - -keywords: fastai -sidebar: home_sidebar - -summary: "```map``` function on free json like structure" ---- - - -
- {% raw %} - -
- -
-
- -
-
- -
-
- -
-
- -
- - -
-

class FreeMap[source]

FreeMap(func='<lambda>', filter_function='<lambda>', flatten=False)

-
- -
- -
- -
-
- -
-
-
-

Examples

-
-
-
-
-
- -
-
-
from math import floor
-
- -
-
-
- -
-
-
- -
-
-
examp = {"somekey":"somestring",
-         "somekey_with_heavy_value":[1,
-                                     "2",
-                                     "word",
-                                     {"function":floor},
-                                     {"are",
-                                      "is",
-                                      "is",
-                                      ("Lovely",
-                                       "example",)}],
-         "someanother_key":"hello this is a long string with verbosity"}
-
- -
-
-
- -
-
-
- -
-
-
capitalize = FreeMap(lambda x:x.upper(),lambda x:(type(x)==str))
-capitalize
-
- -
-
-
- -
-
- -
- - - -
-
<A map function for free structure>
-        Please put in one of the following type: 
-        dict, list, tuple, set, OrderedDict
-        
-        This operation will keep the original structure
-        ======
-        Mapped function
-        <function <lambda> at 0x10fc0fe60>
-        Value Filter function
-        <function <lambda> at 0x10fc0fef0>
-        
-
- -
- -
-
- -
-
-
- -
-
-
capitalize(examp)
-
- -
-
-
- -
-
- -
- - - -
-
{'somekey': 'SOMESTRING',
- 'somekey_with_heavy_value': [1,
-  '2',
-  'WORD',
-  {'function': <function math.floor(x, /)>},
-  {('LOVELY', 'EXAMPLE'), 'ARE', 'IS'}],
- 'someanother_key': 'HELLO THIS IS A LONG STRING WITH VERBOSITY'}
-
- -
- -
-
- -
-
-
-

Flatten and map

-
-
-
-
-
- -
-
-
FreeMap(lambda x:x.upper(),lambda x:(type(x)==str),flatten=True)(examp)
-
- -
-
-
- -
-
- -
- - - -
-
['SOMESTRING',
- '2',
- 'WORD',
- 'IS',
- 'LOVELY',
- 'EXAMPLE',
- 'ARE',
- 'HELLO THIS IS A LONG STRING WITH VERBOSITY']
-
- -
- -
-
- -
-
-
-

Just simple flatten, the default map function doesn't do anything

- -
-
-
-
-
- -
-
-
FreeMap(flatten=True)(examp)
-
- -
-
-
- -
-
- -
- - - -
-
['somestring',
- 1,
- '2',
- 'word',
- <function math.floor(x, /)>,
- 'is',
- 'Lovely',
- 'example',
- 'are',
- 'hello this is a long string with verbosity']
-
- -
- -
-
- -
- {% endraw %} -
- - diff --git a/docs/hf_transformer_data.html b/docs/hf_transformer_data.html deleted file mode 100644 index e1837ec..0000000 --- a/docs/hf_transformer_data.html +++ /dev/null @@ -1,437 +0,0 @@ ---- - -title: Data parts for hf transformers - - -keywords: fastai -sidebar: home_sidebar - - - -nb_path: "nbs/70_hf_transformer_data.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Process IOBES files

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

convert_iob2_file_to_iobes[source]

convert_iob2_file_to_iobes(file_path, result_path)

-
-

Convert IOB2 file to IOBES

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

conbine_iobes_file[source]

conbine_iobes_file(file_paths:List[Path], new_file_path:Path)

-
-

Conbine from multiple IOBES files - into IOBES files

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Dataset

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

class IOBES[source]

IOBES(*args, **kwds) :: Dataset

-
-

Load iobes file for NER training task

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
from transformers import AutoTokenizer
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
tokenizer = AutoTokenizer.from_pretrained("raynardj/roberta-pubmed", add_prefix_space=True)
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
dataset = IOBES("/Users/xiaochen.zhang/data/valid.iobes", tokenizer)
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
for w,l in zip(*dataset[2]):
-    print(f"{w}-{l}")
-
- -
-
-
- -
-
- -
- -
-
in-O
-blood-O
-;-O
-content-O
-of-O
-cAMP-O
-was-O
-also-O
-decreased-O
-in-O
-lymphocytes-O
-by-O
-33-O
-%-O
-.-O
-At-O
-the-O
-same-O
-time-O
-,-O
-total-O
-content-O
-of-O
-T-cell_type
-lymphocytes-cell_type
-was-O
-decreased-O
-1.5-fold-O
-in-O
-peripheric-O
-blood-O
-.-O
-Treatment-O
-with-O
-I-hydroxyvitamin-O
-D3-O
-(-O
-1-1.5-O
-mg-O
-daily-O
-,-O
-within-O
-4-O
-weeks-O
-)-O
-led-O
-to-O
-normalization-O
-of-O
-total-O
-and-O
-ionized-O
-form-O
-of-O
-Ca2+-O
-and-O
-of-O
-25-O
-(-O
-OH-O
-)-O
-D-O
-,-O
-but-O
-did-O
-not-O
-affect-O
-the-O
-PTH-O
-content-O
-in-O
-blood-O
-.-O
-Concentration-O
-of-O
-the-O
-receptors-protein
-to-O
-1.25-O
-(-O
-OH-O
-)-O
-2D3-O
-was-O
-elevated-O
-up-O
-to-O
-39.7-O
-fmole/mg-O
-after-O
-I-O
-week-O
-of-O
-the-O
-treatment-O
-,-O
-whereas-O
-it-O
-was-O
-decreased-O
-to-O
-the-O
-initial-O
-level-O
-24.8-O
-fmole/mg-O
-within-O
-4-O
-weeks-O
-;-O
-simultaneous-O
-alteration-O
-in-O
-
-
-
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
dataset.one_batch()
-
- -
-
-
- -
-
- -
- - - -
-
{'input_ids': tensor([[   19,  3741,  2603,  ...,  1417,  2617, 11576],
-        [ 4590,  2156,   255,  ...,   405,  1182,  6608],
-        [ 6214, 25683,  3809,  ...,    11,     5,  8151],
-        ...,
-        [13998, 25326,  2413,  ...,     5,  2199,    21],
-        [11299,   705, 24811,  ...,   134,  1589,  2032],
-        [ 5804,   924,    14,  ...,   366,  1168,     9]]), 'attention_mask': tensor([[1, 1, 1,  ..., 1, 1, 1],
-        [1, 1, 1,  ..., 1, 1, 1],
-        [1, 1, 1,  ..., 1, 1, 1],
-        ...,
-        [1, 1, 1,  ..., 1, 1, 1],
-        [1, 1, 1,  ..., 1, 1, 1],
-        [1, 1, 1,  ..., 1, 1, 1]]), 'offset_mapping': tensor([[[ 1,  4],
-         [ 1,  2],
-         [ 2,  5],
-         ...,
-         [ 3,  5],
-         [ 5,  8],
-         [ 1,  6]],
-
-        [[ 1,  5],
-         [ 1,  1],
-         [ 1,  1],
-         ...,
-         [ 5,  7],
-         [ 7,  9],
-         [ 9, 14]],
-
-        [[ 1,  5],
-         [ 5,  8],
-         [ 8, 10],
-         ...,
-         [ 1,  2],
-         [ 1,  3],
-         [ 1, 10]],
-
-        ...,
-
-        [[ 1,  5],
-         [ 5,  8],
-         [ 8, 10],
-         ...,
-         [ 1,  3],
-         [ 1,  7],
-         [ 1,  3]],
-
-        [[ 1,  5],
-         [ 5,  6],
-         [ 6, 10],
-         ...,
-         [ 2,  3],
-         [ 1,  1],
-         [ 1,  2]],
-
-        [[ 1,  7],
-         [ 1,  5],
-         [ 1,  4],
-         ...,
-         [ 3,  5],
-         [ 5,  7],
-         [ 1,  2]]]), 'labels': tensor([[0, 1, 1,  ..., 0, 0, 0],
-        [2, 0, 2,  ..., 0, 0, 0],
-        [0, 0, 0,  ..., 0, 0, 0],
-        ...,
-        [1, 1, 1,  ..., 0, 0, 0],
-        [0, 0, 0,  ..., 2, 0, 2],
-        [0, 0, 0,  ..., 0, 0, 0]])}
-
- -
- -
-
- -
- {% endraw %} - -
- - diff --git a/docs/html.html b/docs/html.html deleted file mode 100644 index f1e6765..0000000 --- a/docs/html.html +++ /dev/null @@ -1,791 +0,0 @@ ---- - -title: HTML operation - - -keywords: fastai -sidebar: home_sidebar - -summary: "HTML operation in jupyter notebook, easier life with visualization" -description: "HTML operation in jupyter notebook, easier life with visualization" -nb_path: "nbs/04_html.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

class DOM[source]

DOM(txt, tag, kwargs={})

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Create HTML tag

-
-
-
- {% raw %} - -
-
- -
-
-
btn = DOM("Hello",tag="div",kwargs = {"class":"btn btn-sm btn-danger","id":"test_btn_001"})
-
-btn
-
- -
-
-
- -
-
- -
- - - -
-
<div class="btn btn-sm btn-danger" id="test_btn_001">Hello</div>
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Show HTML raw text

- -
-
-
- {% raw %} - -
-
- -
-
-
btn.text
-
- -
-
-
- -
-
- -
- - - -
-
'<div class="btn btn-sm btn-danger" id="test_btn_001">Hello</div>'
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Display in HTML

- -
-
-
- {% raw %} - -
-
- -
-
-
btn()
-
- -
-
-
- -
-
- -
- - -
-
Hello
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Extend tag

-
-
-
- {% raw %} - -
-
- -
-
-
DOM("a","div")*"span"
-
- -
-
-
- -
-
- -
- - - -
-
<span><div>a</div></span>
-
- -
- -
-
- -
- {% endraw %} - -
-
-

DOM operation

-
-
-
- {% raw %} - -
-
- -
-
-
ul = DOM("","ul")
-ul
-
- -
-
-
- -
-
- -
- - - -
-
<ul class="list-group"></ul>
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
ul.update({"class":"list-group"})
-
- -
-
-
- -
-
- -
- - - -
-
<ul class="list-group"></ul>
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
for i in range(5):
-    ul.append(DOM(f"List item{i}", "li",{"class":"list-group-item paint-red"}))
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
ul()
-
- -
-
-
- -
-
- -
- - -
-
  • List item0
  • List item1
  • List item2
  • List item3
  • List item4
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

image_to_base64[source]

image_to_base64(img:Image)

-
-

Transform PIL Image to base64 for API -Return:

- -
- base64 encoded image bytes
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

data_url[source]

data_url(img:Image)

-
-

Return:

- -
- data url string,
-    can be used as the src value of <img>
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

img_dom[source]

img_dom(img:Image)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

deeper[source]

deeper(x)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

list_group[source]

list_group(iterable)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

col_sm[source]

col_sm(iterable, portions=None)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
col_sm(["foo","bar","return"])()
-
- -
-
-
- -
-
- -
- - -
-
foo
bar
return
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
col_sm(["foo","bar","return"],[2,5,5])()
-
- -
-
-
- -
-
- -
- - -
-
foo
bar
return
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

list_group_kv[source]

list_group_kv(data)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Example: Running JavaScript

-
-
-
- {% raw %} - -
-
- -
-
-
DOM("alert(123)","script")
-
- -
-
-
- -
-
- -
- - - -
-
<script class="list-group">alert(123)</script>
-
- -
- -
-
- -
- {% endraw %} - -
-
-

execute js script

- -
-
-
- {% raw %} - -
-
- -
-
-
DOM("alert(123)","script")()
-
- -
-
-
- -
- {% endraw %} - -
-
-

Longer script

- -
-
-
- {% raw %} - -
-
- -
-
-
paint_red = """
-console.log(document.querySelectorAll(".paint-red"))
-document.querySelectorAll(".paint-red").forEach(dom=>{
-dom.className=dom.className+" text-danger"
-})
-"""
-
-DOM(paint_red,"script")()
-
- -
-
-
- -
-
- -
- - -
- -
- -
- -
-
- -
- {% endraw %} - -
-
-

A class designed for running javascript

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

JS[source]

JS(code)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

JS_file[source]

JS_file(path)

-
-

load javascript file

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
- - diff --git a/docs/image_widgets.html b/docs/image_widgets.html deleted file mode 100644 index 7cbcd95..0000000 --- a/docs/image_widgets.html +++ /dev/null @@ -1,418 +0,0 @@ ---- - -title: Image Widgets - - -keywords: fastai -sidebar: home_sidebar - -summary: "Extra widgets for jupyter noteook" -description: "Extra widgets for jupyter noteook" -nb_path: "nbs/51_image_widgets.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - -
-
-

Imports

-
-
-
- {% raw %} - -
- -
- {% endraw %} - -
-
-

Data url for img tag

-
-
-
-
-
-

Preview images in jupyter notebook

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

image_dom[source]

image_dom(img:PIL.Image, **kwargs)

-
-

Create tag with src='data:...' - with PIL.Image object -return forgebox.html.DOM

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

with_title_dom[source]

with_title_dom(img:PIL.Image, title:str, col:int)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

view_images[source]

view_images(*images, num_per_row:int=4, titles:List[T]=None)

-
-

Create

wraping up images -view_images( - img1, img2, img3, - img4, img5, img6, - img7)()

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Subplot

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

class Subplots[source]

Subplots(total:int, ncol:int=3, figsize=None)

-
-

Simplifying plt sublots -sub = Subplots(18)

- -
@sub.single
-def plotting(ax, data):
-    ax.plot(data)
-
-for data in data_list:
-    sub(data)
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Test on image preview

-
-
-
- {% raw %} - -
-
- -
-
-
import os
-
- -
-
-
- -
- {% endraw %} - -
-
-

Original image

- -
-
-
- {% raw %} - -
-
- -
-
-
HOME = os.environ['HOME']
-img = Image.open(f"{HOME}/Pictures/img02.jpg").resize((200,50))
-img
-
- -
-
-
- -
-
- -
- - - -
- -
- -
- -
-
- -
- {% endraw %} - -
-
-

Data url of the image

- -
-
-
- {% raw %} - -
-
- -
-
-
data_url(img)[:100]
-
- -
-
-
- -
-
- -
- - - -
-
'data:image/jpg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHB'
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Visualize single image

- -
-
-
- {% raw %} - -
-
- -
-
-
image_dom(img)()
-
- -
-
-
- -
-
- -
- - -
-
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Visualize serveral images

- -
-
-
- {% raw %} - -
-
- -
-
-
view_images(img, img, img, img, img, img, titles=list(f"lake:{i}" for i in range(6)))()
-
- -
-
-
- -
-
- -
- - -
-
lake:0
lake:1
lake:2
lake:3
lake:4
lake:5
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Contains more images in a row

- -
-
-
- {% raw %} - -
-
- -
-
-
view_images(
-    img, img, img, img, img, img,
-    num_per_row=6)()
-
- -
-
-
- -
-
- -
- - -
-
-
- -
- -
-
- -
- {% endraw %} - -
- - diff --git a/docs/images/company_logo.png b/docs/images/company_logo.png deleted file mode 100644 index c3453e7..0000000 Binary files a/docs/images/company_logo.png and /dev/null differ diff --git a/docs/images/company_logo_big.png b/docs/images/company_logo_big.png deleted file mode 100644 index 4cc1ab8..0000000 Binary files a/docs/images/company_logo_big.png and /dev/null differ diff --git a/docs/images/doc_example.png b/docs/images/doc_example.png deleted file mode 100644 index d4aa732..0000000 Binary files a/docs/images/doc_example.png and /dev/null differ diff --git a/docs/images/export_example.png b/docs/images/export_example.png deleted file mode 100644 index 1c2829c..0000000 Binary files a/docs/images/export_example.png and /dev/null differ diff --git a/docs/images/favicon.ico b/docs/images/favicon.ico deleted file mode 100644 index c35e955..0000000 Binary files a/docs/images/favicon.ico and /dev/null differ diff --git a/docs/images/workflowarrow.png b/docs/images/workflowarrow.png deleted file mode 100644 index 91a3e81..0000000 Binary files a/docs/images/workflowarrow.png and /dev/null differ diff --git a/docs/imports.html b/docs/imports.html deleted file mode 100644 index bb3faf8..0000000 --- a/docs/imports.html +++ /dev/null @@ -1,41 +0,0 @@ ---- - -title: 03 Imports - - -keywords: fastai -sidebar: home_sidebar - -summary: "standard imports" -description: "standard imports" -nb_path: "nbs/02_imports.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
- - diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 6cdd940..0000000 --- a/docs/index.html +++ /dev/null @@ -1,740 +0,0 @@ ---- - -title: ForgeBox - - -keywords: fastai -sidebar: home_sidebar - -summary: "Data science comprehensive toolbox 🛠⚔️📦" -description: "Data science comprehensive toolbox 🛠⚔️📦" -nb_path: "nbs/index.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - -
-
-

forgebox logo

- -
-
-
-
-
-

Installation

Easy simple installation in 1 line

-
pip install forgebox
-
-

If not specified, you need anaconda3 for most of the tools, python shold be at least >=3.6

- -
-
-
-
-
-

Features 🚀 Briefing

This is a tool box with comprehensive utilies, to put it simply, I just hope most of my frequetyly used DIY tools in in place and can be easily installed and imported

-
- -
-
-
-
-
-

Lazy, fast imports 🤯

-
-
-
-
-
-

The following command will import many frequent tools for data science, like pd for pandas, np for numpy, os, json, PIL.Image for image processing

-
from frogebox.imports import *
-
-

No more🚫 following typings

-
import pandas as pd
-import numpy as np
-import os
-import json
-...
-
- -
-
-
-
-
-

Categorical converter

Mapping and converting categorical infomation

-
- -
-
-
- {% raw %} - -
-
- -
-
-
from forgebox.category import Category
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
az = list(map(chr,range(ord("A"), ord("z")+1)))
-print(az)
-
- -
-
-
- -
-
- -
- -
-
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
-
-
-
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
cate_az = Category(az)
-cate_az
-
- -
-
-
- -
-
- -
- - - -
-
Category Manager with 58
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
cate_az.c2i["R"], cate_az.i2c[17]
-
- -
-
-
- -
-
- -
- - - -
-
(17, 'R')
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
cate_az.c2i[list("ForgeBox")]
-
- -
-
-
- -
-
- -
- - - -
-
array([ 5, 46, 49, 38, 36,  1, 46, 55])
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
cate_az.i2c[[ 5, 46, 49, 38, 36,  1, 46, 55]]
-
- -
-
-
- -
-
- -
- - - -
-
array(['F', 'o', 'r', 'g', 'e', 'B', 'o', 'x'], dtype='<U1')
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Padding missing token

- -
-
-
- {% raw %} - -
-
- -
-
-
cate_az = Category(az, pad_mst=True)
-cate_az.c2i[list("Forge⚡️Box")]
-
- -
-
-
- -
-
- -
- - - -
-
array([ 6, 47, 50, 39, 37,  0,  0,  2, 47, 56])
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Get a dataframe of file details under a directory

-
-
-
- {% raw %} - -
-
- -
-
-
from forgebox.files import file_detail
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
file_detail("/Users/xiaochen.zhang/.cache/").sample(5)
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pathfile_typeparentdepth
36/Users/xiaochen.zhang/.cache/torch/transformer...jsontransformers7
13/Users/xiaochen.zhang/.cache/torch/transformer...jsontransformers7
51/Users/xiaochen.zhang/.cache/langhuan/task_NER...jsontask_NER_210121_1405137
32/Users/xiaochen.zhang/.cache/torch/transformer...locktransformers7
58/Users/xiaochen.zhang/.cache/langhuan/task_Cla...jsontask_Classify_210128_1647107
-
-
- -
- -
-
- -
- {% endraw %} - -
-
-

JS style async

-
-
-
- {% raw %} - -
-
- -
-
-
from forgebox.asyncing import Async
-from time import sleep
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
def something_time_costing_but_you_dont_want_to_wait(x):
-    sleep(x)
-    return f"slept for {x} seconds"
-
-def task2_you_will_perfrom_after_the_time_costing_one(x):
-    print(f"[result]:\t{x}")
-    return 1
-
-print("1111111111")
-
-Async(something_time_costing_but_you_dont_want_to_wait)(2)\
-.then(task2_you_will_perfrom_after_the_time_costing_one)\
-.catch(print)
-
-print("22222222222")
-
- -
-
-
- -
-
- -
- -
-
1111111111
-22222222222
-[result]:	slept for 2 seconds
-
-
-
- -
-
- -
- {% endraw %} - -
-
-

HTML in notebook

-
-
-
- {% raw %} - -
-
- -
-
-
from forgebox.html import DOM, list_group, list_group_kv
-
- -
-
-
- -
- {% endraw %} - -
-
-

This will map a clear HTML table view of wild tree type json structure/ list

- -
-
-
- {% raw %} - -
-
- -
-
-
bands = ["police", "headpin", {"ac":"dc"}]
-list_group(bands)()
-
- -
-
-
- -
-
- -
- - -
-
  • police
  • headpin
    • acdc
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
questions = {
-    "question":"answer",
-    "another":{
-        "deeper question": "answer again"},
-    "final":{
-        "questions": ["what","is","the","answer", "to",
-            ["life", "universe","everything"]]}
-}
-list_group_kv(questions)()
-
- -
-
-
- -
-
- -
- - -
-
  • questionanswer
  • another
    • deeper questionanswer again
  • final
    • questions
      • what
      • is
      • the
      • answer
      • to
        • life
        • universe
        • everything
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Coding html in python

-
-
-
- {% raw %} - -
-
- -
-
-
title = DOM("Title example","h5", kwargs={"style":"color:#3399EE"})
-ul = DOM("","ul");
-for i in range(5):
-    ul = ul.append(DOM(f"Line {i}", "li", kwargs={"style":"color:#EE33DD"}))
-
-title()
-ul()
-
- -
-
-
- -
-
- -
- - -
-
Title example
-
- -
- -
- - -
-
  • Line 0
  • Line 1
  • Line 2
  • Line 3
  • Line 4
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Free style mapping

-
-
-
-
-
-

Works on every value of a complicated dictionary structure (eg. list in dict in list in dict, etc,. 😳)

-
from forgebox.freemap import FreeMap
-
-# flatten decides if we want to flatten the strucuture
-freemap_tool = FreeMap(
-    <function/callable applying to every value>,
-    <function/callable that filters every value>,
-    flatten=True
-)
-
-data2 = freemap_tool(data1)
-
- -
-
-
-
-
-

Interactive Widgets

Interactive widgets work with in jupyter notebooks

-
- -
-
-
-
-
-

Search box 🔎 for dataframe

This will create an interactive text input box to search through the pandas dataframe, within the columns you set.

-

if manual is set to False, the search will respond to each of your key press, it's fast but will suffer terrible user experience if the dataframe is huge in size.

-
from forgebox.widgets import search_box
-
-search_box(data_df, columns=["col1","col2"], manual=False)
-
- -
-
-
-
-
-

paginate

You can browse through a pandas dataframe like fliping pages 📄.

-
from forgebox.widgets import paginate
-
-paginate(your_dataframe, page_len=10)
-
- -
-
-
-
-
-

Single button callback

a fully functional page with a single button, this single button is bonded to a function

-
-

This is as much code as you need, to build a fully functional interactive page shows sql table from jupyter, that you can: choose which table to visit choose how many lines you want to show, (with a slider)

-
    -
  • configure the where condition with a text box on front end
  • -
-
tablename_list = ["pubmed", "patient", "users", "drugs"]
-
-from forgebox.html import DOM
-def show_sql_table(sql_input:str) -> str:
-    with engine.connect() as conn:
-        df=pd.read_sql(sql_input, con=conn)
-    # display the table as html
-    DOM(df.to_html(),"div")()
-
-@SingleButton(callback=show_sql_table)
-def abc(
-    limit:{"typing":int, "default":10, "min":5, "max":20},
-    where_condition:{"typing":str, "default": "where 1=1", },
-    table:{"typing":list, "options":tablename_list}
-):
-    return f"SELECT * FROM {table} {where_condition} LIMIT {limit}"
-
- -
-
-
-
- - diff --git a/docs/inter_widgets.html b/docs/inter_widgets.html deleted file mode 100644 index a046324..0000000 --- a/docs/inter_widgets.html +++ /dev/null @@ -1,985 +0,0 @@ ---- - -title: Interactive tools - - -keywords: fastai -sidebar: home_sidebar - -summary: "Very helpful interactive tools" -description: "Very helpful interactive tools" -nb_path: "nbs/05_inter_widgets.ipynb" ---- - - -
- - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

display_df[source]

display_df(df)

-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

search_box(df, columns, manual=False, max_rows=10, callback=display_df)

-
-

create a search box based on dataframe -df: pandas dataframe -columns: str, dataframe field name -manual: bool, search the dataframe on when click the button(manual=True), - or on keypress reaction to inputbox (manual=False), default False -max_rows:int, max rows of show result, default 10 -callback: python callable, discribe the action you want to put on - search result (a filtered dataframe), default is to display the dataframe

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Search text within dataframe columns

We can have any dataframe we like:

- -
-
-
- {% raw %} - -
-
- -
-
-
df = pd.read_csv("~/Downloads/mesh_keywords_202004201804.csv").head(2000)
-
- -
-
-
- -
- {% endraw %} - -
-
-

Put the dataframe and target column names into the search_box()

- -
-
-
- {% raw %} - -
-
- -
-
-
search_box(df,columns=["keyword",])
-
- -
-
-
- -
- {% endraw %} - -
-
-

If your dataframe is slightly huge, and slow to respond, you can use manual=True to turn off the auto keypress response

- -
-
-
- {% raw %} - -
-
- -
-
-
search_box(df,columns=["keyword",],manual=True)
-
- -
-
-
- -
- {% endraw %} - -
-
-

Interactive pagination

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

paginate[source]

paginate(df, page_len=20)

-
-

Paginate dataframe in jupyter notebook interactively -Like you can flip through the page

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
paginate(df)
-
- -
-
-
- -
- {% endraw %} - -
-
-

SingleButton widget

-
-
-
-
-
-

A single button widget

-

It's like interactive_manual with callback

-

You can make an fully interactive featured widgets if there is only one button to get new page

-

Example

@SingleButton(callback=execute_sql, btn_text:"run command", btn_style="primary")
-def makeup_some_sql(
-    table={"typing":list, "options":["table_a", "table_b"]},
-    limit={"typing":int, "max":1000, "step":10, "default":100},
-):
-    return f"select * from {table} limit {limit}"
-
- -
-
-
- {% raw %} - -
- -
-
- -
- - -
-

make_hboxes[source]

make_hboxes(*widgets, sections:int=2)

-
-

Make a list of HBox, with each hbox - contans {sections} of widgets at most -widgets: widget from ipywidgets -sections: int

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

class SingleButton[source]

SingleButton(btn_text:str='Run', btn_style:str='danger', callback:Callable=<lambda>, sections:int=2)

-
-

A single button widget -It's like interactive_manual with callback

-

Example

@SingleButton(callback=execute_sql, btn_text:"run command", btn_style="primary")
-def makeup_some_sql(
-    table={"typing":list, "options":["table_a", "table_b"]},
-    limit={"typing":int, "max":1000, "step":10, "default":100},
-):
-    return f"select * from {table} limit {limit}"
-
- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Example for SingleButton

-
-
-
-
-
-

This is a sample callback

- -
-
-
- {% raw %} - -
-
- -
-
-
from forgebox.html import DOM
-def sql_callback(x):
-    DOM(x,"h3")()
-    # and we execute more code like,
-    #    eg. run this line in sql
-    return x
-
- -
-
-
- -
- {% endraw %} - -
-
-

Now we can have an interactive single button page, with multipule input widgets

- -
-
-
- {% raw %} - -
-
- -
-
-
@SingleButton(callback=sql_callback)
-def abc(
-    limit:{"typing":int, "default":10, "min":5, "max":20},
-    where_condition:{"typing":str, "default": "where 1=1", },
-    table:{"typing":list, "options":["image_urls","patient_data"]},
-):
-    return f"sql > SELECT * FROM {table} {where_condition} LIMIT {limit}"
-
- -
-
-
- -
- {% endraw %} - -
-
-

Dataframe labeler

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

class Labeler[source]

Labeler(df:DataFrame, options_col:str, result_col:str='label', show_callback:Callable=None, auto_fill_in:bool=True)

-
-

An interactive tool labeling pandas dataframe - row by row

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
df = df.loc[1:].reset_index(drop=True)
-df.head()
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
keyword
0Appetite Regulation
1Hymecromone
2Round Ligament of Uterus
3Sugar Acids
4Nogalamycin
-
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Design a dataframe with a column assigned with options

-
-
-
- {% raw %} - -
-
- -
-
-
df.loc[:,"length"] = df.keyword.apply(len)
-df["options"] = pd.Series([["A","B"]]*len(df))
-df
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
keywordlengthoptions
0Appetite Regulation19[A, B]
1Hymecromone11[A, B]
2Round Ligament of Uterus24[A, B]
3Sugar Acids11[A, B]
4Nogalamycin11[A, B]
............
1994Alcoholics Anonymous20[A, B]
1995Lymphocyte Cooperation22[A, B]
1996Anthocerotophyta16[A, B]
1997Traction8[A, B]
1998H(+)-K(+)-Exchanging ATPase27[A, B]
-

1999 rows × 3 columns

-
-
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
def show_keyword(idx: int, row: Dict[str, str]):
-    kw = row["keyword"]
-    length = row["length"]
-    return f"""
-    <div>Keyword
-    <strong class='text-danger'>{kw}</strong>
-    (with length:{length})
-    </div>"""
-
-lbl = Labeler(df, options_col="options", show_callback=show_keyword)
-
- -
-
-
- -
- {% endraw %} - -
-
-

Start labeling

-
-
-
- {% raw %} - -
-
- -
-
-
lbl()
-
- -
-
-
- -
- {% endraw %} - -
-
-

{% include image.html alt="image.png" file="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfkAAACHCAYAAAAV6SDhAAAgAElEQVR4Ae2d2bMVRbbG+Qd89cknH3zoB6PDCCO6w+gIoyO4hqGEl/Zi2zRevBJ6wQZkaKS1MQD7oqiIA5O0CC3YiICCSIM0k4KIiAOIIIMigwgyjwIy5I1f4irz1Kl9dp3trk3Vri8j6lTtrKwcvly5vlwrs+p0cApCQAgIASEgBIRAUyLQoSlbpUYJASEgBISAEBACTiQvIRACQkAICAEh0KQIiOSbtGPVLCEgBISAEBACInnJgBAQAkJACAiBJkVAJN+kHatmCQEhIASEgBAQyUsGhIAQEAJCQAg0KQIi+SbtWDVLCAgBISAEhIBIXjIgBISAEBACQqBJERDJN2nHqllCQAgIASEgBETykgEhIASEgBAQAk2KgEi+STtWzRICQkAICAEhIJKXDAgBISAEhIAQaFIERPJN2rFqlhAQAkJACAiBzEh+y4EfXL9Zh1y38Qf9cfjwYadDGEgGJAOSgWLKwPHjx9358+fFmgVDIDOSDwkeotfALubAVr+p3yQDkgGTAYheoVgIZEbyZsHb2YREZykMyYBkQDJQXBkoFsWptiJ5LSPIyyIZkAxIBlLLgGizWAiI5DW4Uw9uWV/Ftb7Ud+q7eslAsShOtRXJi+RF8pIByYBkILUMNJI2T5w44c6cOdPIIpuuLJG8BnfqwV0vS0D5yKqUDBRXBiqx4MWLF93s2bNdv3793F133eWefPJJd+jQoRbJ06SxB5CRDh06uGnTplmUP2/atMl17tzZHThwoEU8P7Zt2+aGDx/uunfv7h588EG3atWqzNK0yjinESJ5kbxIXjIgGZAMpJaBSlzWtWtXT8pXX321u+GGG/z1FVdc4Xbs2BE9kiaNJR4/frzj+VOnTlmUO3v2rCd4yH/Xrl1RPBcLFiyIyrzxxhv9s6SbOHFilK5eaaIMC3AhktfgTj24ZX0V1/pS36nv6iUDSby2aNEiT7B9+/Z1WOsEi+vRo0eL322lCfO+9tprHWkJq1evdj179nRXXXWVLydO8pD/lVde6e/v27fPP3PkyBF3/fXXe7Lnul5pwjoW4VokL5IXyUsGJAOSgdQykERsuMgh3v3797e4fc011zjImpAmjT28Zs0an9+6det81Pz5893NN9/sD/KMk/yGDRt83BNPPGFZ+POcOXN8/KxZs1y90rQooAA/RPIa3KkHd70sAeUjq1IyUFwZSOK1efPmuaFDh7a4heWMu/2mm27y8WnSWAZY7VjhSeGFF15oRfJY+hD/pEmTWjyyfPlyHz969GjvDahHmhYFFOCHSF4kL5KXDEgGJAOpZSANr+GyHzBggCfYl156KfGRSmmOHTvmn5s8eXLic0kkjwcBAsfaD0P//v19POd6pQnzL8K1SF6DO/XglvVVXOtLfae+q5cMVCO2vXv3Rpvj7r777sTv3beVhkkBhF3pE7pJJE+d7rnnHv8cO++nTp3q1/DJh2PgwIG+2vVKUw2DPN0XyYvkRfKSAcmAZCC1DLRFYNOnT492tY8bN85duHChVfJqaXDT9+rVq9VzFlGJ5NmFj/eAJQKI/brrrnO2Js/rfIR6pbG6FOEsktfgTj2462UJKB9ZlZKB4spAJWIbNmyYJ9dOnTq53bt3JyarloaNdhD02rVrE58nshLJhw/Ya3e2Vv/KK6+Et/11vdK0yjhnESJ5kbxIXjIgGZAMpJaBJA5buXKlJ2csaXuFLp4uTRpembPd+PHn7XcSyVMmr9DZJj9L27t3b18vPpxTrzSWd1HOInkN7tSDW9ZXca0v9Z36rl4ykERu9pEbPmAzZcqUFsfixYv9I9XSYFnjag8/XpNUVhLJk471f7wAffr08R/GGTJkiP/NOryFeqWx/IpwFsmL5EXykgHJgGQgtQwkERtfuYNgk46OHTv6R6ql4fO1PM+Ha9oKlUieXfl4EsIP5kDwvMpnoV5pLL8inEXyGtypB3e9LAHlI6tSMlBcGciK2Pju/Pr16+uS/c6dO925c+fazKteadosJAc3RfIieZG8ZEAyIBlILQM54C1VoR0IiOQ1uFMPbllfxbW+1Hfqu3rJQDv4RUlzgIBIXiQvkpcMSAYkA6llIAe8pSq0AwGRvAZ36sFdL0tA+ciqlAwUVwbawS9KmgMEMiP5PtP3ujuf3R0dGtTFHdTqO/WdZEAygAxU+tRsDrhMVaiAQGYk//mek+6eCZ+5TsPW+ENKQkpCMiAZkAwUVwYg+PPnz1egEkXnFYHMSD6vDVa9hIAQEAJCQAiUBQGRfFl6Wu0UAkJACAiB0iEgki9dl6vBQkAICAEhUBYERPJl6Wm1UwgIASEgBEqHgEi+dF2uBgsBISAEhEBZEBDJl6Wn1U4hIASEgBAoHQIi+dJ1uRosBISAEBACZUFAJF+WnlY7hYAQEAJCoHQIiORL1+VqsBAQAkJACJQFAZF8WXpa7RQCQkAICIHSISCSL12Xq8FCQAgIASFQFgRE8mXpabVTCAgBISAESoeASL50Xa4GCwEhIASEQFkQEMmXpafVTiEgBISAECgdAiL50nW5GiwEhIAQEAJlQUAkX5aeVjuFgBAQAkKgdAiI5EvX5WqwEBACQkAIlAUBkXxZelrtFAJCQAgIgdIhIJIvXZerwUJACAgBIVAWBETyZelptVMICAEhIARKh4BIvnRdrgYLgfwhcPLkSXfmzJn8VUw1cidOnHDnzp0TEgVFIDOSZ9DecMMN7rHHHmsFzb59+9wtt9zi73/wwQet7hc1YtiwYe7222/31T+4/Ss3s8fd/lg/541CNilsg7WF87w/D3DvTRjnDm7fnot2fbVyRYT16WPHMqnTrPt6RGWEWNj19vffd42oRyaNq5DpmRMn3MkDB9zJQ4cqpKhP9Lfffus6dOjglixZ0u4MZ8yY4fXI4cOH/bNnz551e/fubUFKPXv2dH369GlX3l988YXP95133mnXc/VKTBtOnToVZffhhx/6+qxbty6KS3uxa9cu9/jjj7tu3bq5/v37u0WLFrV6dOvWrQ79ddddd/k0y5Yti9Jcf/31bvDgwdFvXRQLgcxInkHHwL377rtbIMKAvuaaa/y9adOmtbhX9B9du3Z1V111lW/Gt59vcJNv+Q9/vD/xhUI2LWyDtSV+Xjv15cvets/mzo2wzoqQ4u2O/960YIFrRD0aCfbSJx73uE69/bZMi+3bt6+79tpr3cWLF9tdzrPPPut1yf79+/2zK1as8L8XL14c5fWrX/3K/fa3v41+p7n46KOPfD5z5sxJk7yuabCa0Z2PPPJIlC/ETNzKlSujuDQXa9ascVdccYV/9sYbb3RXXnmlvw5Je9WqVT6OdBhmlMPx5JNP+iKmT5/uf2/bti1NkUqTMwQaSvJ79uyJCP7111/PGRQ/vzrNTPJYrCvHjXVLRz7mLdqQ5HauXfvzwfsZOTSCXK29EB44xI/9X24TydfQh1999ZUnkFon/KdPn3YHDx6MSjaSD63VopL8kCFDonbVSvK0HfLGUifgHejYsaPHfPuPnjiIHfJHPxOOHTsWTQbOnz/v8I5wH4+IQvEQaBjJ796921199dVeuBYsWNAKKQRp7Nix7o477vDHhAkTIncVLjncTIdibsPVq1f7+ClTpvjzzp07o3yXLl3q4z755JMobuPGjT5u/fr1URwzdYT3pptu8vfCmTJLDpT78ccfu/fee8+7/EwZbd682T300EP+uTvvvNPNnz/f1UryuMWXj3rKvX7//7rX/ue/3Zv9+rqPX/2nOx+sg+35bL3799+GO+82vvce9/bQIS5OrqT/eMZ0N3/wIDe7573u3WdGu++2bonauvPDNW7pEyO9q/34vu/cksf/zxP2yUBJRomdc6ElH/dGrHt9dmQ9z+jeLXzM7VjzgVs84m9u5r33uLce/LP78OV/uB++/z5KE9aDMhY+8lffrmVPPeEgSwtp01Ui+a3LlrlFw4f6elAf3OlheGf00x4PsN34r/nu9T/1dB+8NClMEl0byYNrpVCpHm3hgTucPuHYufbDKOv3xo/1cRvefDOK+3zemz5uxZjn3OmjR6PnWDYhPXVb8PBgt+vjjzzeqyf93cfNfaC3Y8kobim3hQ/YTP/jnVEfU7+ty5a6sE9Mhl67p7vv70tpfnLznj971tGn9mzUkOCiV69enkAY/7jrGW/tGcfLly/3z7BujB647bbbvI7p1KlT5GI2kid/xigWbe/evVuUE1TJXyZZ8m3pKB56/vnnHfqBJUiWB/AeJJWDRTx8+HC/ZHn//fc7ysKdjp5D/4ABlvR1113nr7/55hvvYidu3rx53q0OUdNW2hz264ABAxwHgQkQz5BfGGbPnu3jyYt9EKT5y1/+Eibx9Sb+u+++8/Esu/LblkVaJNaPXCPQEJJn0BrBh2s9hsz333/vWPdBiFirt5kmg4SZJ1Y/9yZNaqmAIVdmqW+//ba/P27cOMvScY9nIGILDCzi2BNAgNz5Td26dOkSzV6ZbBBIx30UEWcO7pl7i98ok9DF1V53/Tfr10WK1IjEzpAf4ZtPP6mYZsvSS+uYrJ9CtvZseGa9mPDRK9Oi+1iklubonm/9/fiftkietK/e1TXKwyYkWLiWb3ie1qVztLYb1iNMY9e7f5yYpU2XRK5MiCy/8AzxWbD4f3a9I0q76NFhdrvF2dK2l+Sr4QFuUzrd7MuHoAkQv5UHbha4Jp6J05Fdu6I09rw9wznsG4v/dNZrlpWfMFp8eDZ8wji7hrDDPgllyDCkXAvb318V1dFk0O7Z+Re/+IUnK35D2Iyp9ozjZ555xj+Dux7L15YCGdOQO4GzjV90io1XxmqlzX5xkq+mo6wc03OVylm7dq3XWegtSBoit7qhj954440oDuuZ+xgnZsmTlvjOnTtHbvgXX3zRt5M/lhfXTHwefvjhVi5+W+LASGJpAKPHljt4jv0AtIMlFAvvvvuuz/tyLF9YHXSuDYHMSZ4BxmBC+BBscxGF1R0xYoS/H25ymTVrlo9DgJlB8+xvfvOb6DEEmDyZMSOo3IdwCcxs+c19BokFJhKWhykUZvY//PCDT3LkyJFossHExEiefB599FHHQCdv8iF/NudYYEZNuvaS/IK/PuQVIYr62N697uKFC+5fDw2OlKO7eNFbQyha0mARcxihY30Slo960j/zj/+81VusWHNY0jwHOVw4f76FgiYesljx/HOOCUJSqEbytmZLXoe+/trt2fBZVO+Fjzzsvtuy2VvI3OewSUtIFNSRcrYuXxaRHd4MQtp0cZLHQrUyP535mtu7aWMLUju045LHx9JwBiMw3BKs5YaYhGnj1yxhEOL1SIvH20Mf8fWlf+n/zYv/HdWfsrCYD+/cGcWx/h+SvPV5iBfPUR+wsEkAniJCGnyO7N7t+4t8eJ7f3x850qJPuGcy9MHkSVH9DF+8J6ShfrQrHhh3jBmzNGsZxyHJk38ldz3lzJw5M6oCm8yIY8KeFOIkX01HkYdNJtoqB/2D7vjyyy+jYvv16+frYu5wW5NPcteje9B9hKNHj/rn8EJawJMwdepU+9nqjNue8iFxLP0w0GabAMXriN4O+yp8Ttf5RiBzkkcwEBg2kXDNQDBSNWiYMTKj37BhQ4uDGSuuNQIzUp7fsWOH/41ri98IJuHee+/1vxFcyJd79gwuJtbtiDMr3Vxi7DwNg82YX3rppYjkEXwLzHLJJ2m3Lm1oL8kf3bPHHfzqS69Ej+/b57B4QisM5YjrFGXJgSX58avTHR4AyPncj68dmSKHSMmDAxe7PYcrOCSBcMPcksdHeNc97ns7yLsayb/73DNR/rjZcRlTHnUJ3fMsG1g9mLSE9Qh36K+d9nKU7sT+/anTxcnVJkm4mw0LXM1WB94MINhvSKjSRMf63dImnfEaEOL1SIvHtneWR3VhQoJ7OywHUg+XR3DVhyT/0fRXrJoRob854IEoDg8B+ZlXIC0+NokLN96FfRfKUOh9WPOPKZ7UTSZXjh0T1SW8sHE6ZsxP99s7jtOSvI1LKx8rlnGMyzopxEk+jY4ygybMLyzH3iIYNGhQmCTSM2lInk1wYYDgQ4s7vBe/ZvKBLubAoxAPLCOwIQ9vKtjg3WTJkmATMuIUioVA5iSPQNkauLm94+s/CFSlwwYnAkga2/GJuyoUbtb5uY+Fjlufcm1QsV5uLv+vv/7a95Ct3cW7i/Uv8mGCYJZ8OKPmVRbujx8/Pv5oTWvyWEhYQ6FSD68heRQoG9/CeK5RvpDYqcOHW92Lp9244F8tSBMStRBPy292qVcjeYjEnoXUjTxCly1lsN5t6bBKQ6KwOnBmImLpWCdPmy5OruFasuUXnvGeECyOiU21YGnxoOChCA9b7ojXIy0eYGf5Q5BWf5scLR7xqH9tkTRz+tzvqxqSfOh9MBd62Cae51kjecvfyoyfDZ9qJB/KEJViLwl50f8suVi+4UQuxHnhwoV+LIWWb3vHcVqSN2PByofkGMdvBnse7B7nOMmTttJhOgqSb6sc0x1///tPS0ZWJnmnIXnc5mHAexnqwfCeXWOYoC8pg/oleVMtrZ0xhkjP8oGF0OiyOJ3zj0DmJB++Qsf6uq2ZhbtfGSRYy2ySix+bNm2KUGStHmvZXs8zq5wEtskEcuZdT5txkn7gwIF+AIWue+qFEMfX5D777DMf//TTT0ckzxqWBdxsPMdGmXi4+eab223Jm9WONfnRP1/xm+mwfExBhm5ONuhhxbORyu5jLZ374Yfo95w+f3JfLHq71YHHICRNNkVZwLJd8dyzLQ6Ipy2Sx/tgdXjlzv/yWUEsxBmZWP7U2dKSb1iP0IIO3cjknzZdnFxxS1MehJeExTfrPvVVszqZZW/1TTpb2vasyafFg/Jsomdr22B4aMeOqB1mFa+bPctXrzrJj4iaESf5tPhUI/lQhiiMyYbhZDJqSy9RZYIL29vyc8ZxWpJnjTwMRrhpST6NjoLk2yoHVzm6A9d/GMztnobkw43B5IHV3RbJQ+jUHaMHV364SY/nmczgDWBjcRjYcEddbRPfhQsX/O/u3buHyXRdAAQaSvLgAYkjPAgdM0wCO+r5jbBbYN2JQRO+K2rr9LjKyePAgQOW3J/52AMCz4zTLG0IHqInbuTIkVF6m6nabnm7gZeBvNmdb5Y8u2Yt2LohkxWuLZgHwGb1IUFi0UFg8SO0wFdP+mnzjCl8FCYkj8JkEsDGJwtGIKSBOFGmXEMS/Cbs27Qp+oALHoOQNM//uA/B8ks6J7UBRb76xYmRW5gyv3h7oX+cHdz85vjqR6VBXWwigwVJCOuxZspkH8eeASYo9vy506dTp4uTPPsMLB/Wsgl8JAcc8YjguidYmqxIPi0e1AVPi9WHsy0BmGVu9078uNv555B8WnyM5CnbZCrsu7gMQfo2GbH6hpv9POjBH5swM0bD0J5x3CiST6OjqpG87S1CH4VLlixXoHOyIHkmHehW3gZKCp9//rkvOzTGSMd3BqiTLaWYV9Q8qUl5KS6fCDSc5IFh9OjRXoCwzHkP04gfS5vXO+bOnes30SFk4QYVrG4ElngGXTyYS577rO8T3nrrLZ+euNArgFcB4id+1KhRntRZj+K3udySSJ48TbFgubMUwP4A81AkkbwpvPj54NfbPXkTD4njnjWXp6VFuTIBsN+4Ut8ZPSpSpmxcI4SubtLaxjyuzcXbloL2mcT+hCRv5cfPbBoz64Cd4maJkg5CpV32DEsLhLAe3GMSgOVq6WwNN226OMkzeQrJJsSC+DPHj/t6WHlZkXxaPKgM6+xWH86QPoHd/hYfWsU/h+TT4hPu6aAO9EvYJ3GSp77hxIBnaFelgNwwBnElh6E949jGou0ONzc7EwWbwFcj37Bsu7Z8bDd5Gh2VphyrL9bz5MmT/ds/6BwOI3lw4Teb7EjDq8O2V6iaJW950Q7b80BZbAyOH2CG/rXNdnhA0WcvvPCC17PoWtuzxGuB5M19hWIhcFlIHtePvSaHW5zAO6z2+gnChODFN5mQ7sEHH/TCFrr7DXLbcY9wUgbBXPuQcDywg54BYAODMzNa8yhUInkG4VNPPRVNOHgOwqdNRvJY0aacK51xx/LudkhIkKLttuY51n6x5m19NswLt6tZdrQN6zkkS/LCVWsucTZo2fNJCjqOT6U2YF3OG9jfbVrY+nsH7B/gPX0rhzN1+jJYSwyJAoIN07LpzF7HS5suJPlThy593pTd/nxTwPIGY+ocvodv97IgeatHGjwMdyZjVic2YRLA2OI+fHmKJW2x8c5eo+SmWf6QrYW4u574NPjwtkc4QfKv0FWRId7qsPrikaoW2GgH0YdesfaMY7OC7YM4LNthvdqYpnzIl7EZhmrueiP10J1fTUelLQcvouk69MXLL7/sMbC3DKinGRy0gwmHkXz8bYC4uz5s96uvvhrhYPHh2Vz0fASHz3GH99C/4ea8iRMn+vvhNwxCPHWdXwQyI/lam8ysNe6GD/Pilbe4Ugjv13KNYmDtKlQ0afKB7BF624Ga5pmkNLg5serZwBWuwcfTkg4LDqJqy0KCYMxNHc+jUb99m7Zvd0Z2YbkheTPZ4A0BNmfxTBjSpgufiV/jCfF5B0sr8TSN+N0WHo0ov1IZafBh6YSJIksqlQLeEWQ4nLSFE7tKz9kGOLOYK6XLU3w1HdVWXdltbx5FvIkEdAgEi5V/OQN6EM/p8R89XVYXDCaMJCx9heIhkDuSrwQha97MpBkMSf/0ptJzis8fAnHyrlTDtOkqPa/4xiEQvkGBJY8Xpa0Ja1gzrGwsxzIE2oqRgqeAgEGDFxC9Fn53I09Y2BsPfIJYoXgIFIbkGRgMBNxcfFtZobgIrH9jtl+iwIXe1rJB2nTFRaJ5as7HjFgeYmmGTwnj6k8b7I0W/plKswdeJzZdZvuL0Gu2UTiP7WdikvRdkDzWVXVqjUBhSJ7335lRxl1JrZukGCEgBIqGAN/BsM1zRat7e+vLsiBf5mPDLp/5tu/DtzefRqVneUF6t1Fo17+cwpB8/ZuuHIWAEBACQkAINDcCIvnm7l+1TggIASEgBEqMgEi+xJ2vpgsBISAEhEBzIyCSb+7+VeuEgBAQAkKgxAiI5Evc+Wq6EBACQkAINDcCIvnm7l+1TggIASEgBEqMgEi+xJ2vpgsBISAEhEBzIyCSb+7+VeuEgBAQAkKgxAiI5Evc+Wq6EBACQkAINDcCIvnm7l+1TggIASEgBEqMgEi+xJ2vpgsBISAEhEBzIyCSb+7+VeuEgBAQAkKgxAiI5Evc+Wq6EBACQkAINDcCmZH84cOHnQ5h0MwykKQamrm9apvGMzKgUCwERPKajGgyVqMMJA11EaGIsNllIEnuFZdfBETyNSr4Zh/Ial91skoa1sKtOm7CqNgYJcm94vKLgEheJC9LvkYZSBrWIrBiE5j6r3r/Jcm94vKLgEi+RgUvZVBdGTQ7RknDutnbrPZJ7pPkXnH5RUAkL5KXJV+jDCQNa5GgSLDZZSBJ7hWXXwRE8jUq+GYfyGpfdbJKGtbCrTpuwqjYGCXJveLyi4BIXiQvS75GGUga1iKwYhOY+q96/yXJveLyi4BIvkYFL2VQXRk0O0ZJw7rZ26z2Se6T5F5x+UVAJC+SlyVfowwkDWuRoEiw2WUgSe4Vl18ERPI1KvhmH8hqX3WyShrWwq06bsKo2Bglyb3i8ouASL4JSH7w4MGuW7dubvHixbLKG9ifScNaBJYdga1YscLLObIeHvfdd58bMWKE27Jli+S/AfKfJPeKyy8CIvkGDIosFf+6devcL3/5S3/06tVLSq6B/Zk0rLPs67LnvWDBAi/nXbp0cQ888IA/evfu7W677TYf37FjR7dz506NgYzHQJLcKy6/CIjkMx4QWSvmkSNHegU3aNAgf966dauUXIP6NGlYZ93fZc7fSH7GjBmtZHzUqFFe/ufOndvqXpkxy6LtSXKvuPwiIJJvECFkMdj279/vfv3rXzusmTVr1nglN3bsWCm5BvVp0rDOop+V56UlgLZIft68eV7+p02bJvnPWP6T5F5x+UVAJJ/xgMhSQZti40w5t956q8NleejQISm6BvRr0rDOsr/Lnnclkt++fbvr2bOnJ/mNGzdK9jOW/SS5V1x+ERDJZzwgslTMKDYs+X379nnFhhXP+vzSpUul6BrQr0nDOsv+LnveRvJMZP/whz/4g4mt7UmZM2eO5P4yyX3SWFBcPhAQyTdgUGShnDdv3uyV29ChQyPFhhWDwhs4cGAUl0XZyvOS+zhpCAub7HbXG8n//ve/d/379/dHv379XPfu3b3cQ/gsW6kPsusDsFUoFgIi+YKS/JgxYyILxiyZ8Lxjxw4pu4z7Nmmoi2CyIxgj+aSNd5988okfD5C++iC7PhDJJ436fMeJ5DMmgiwUzsGDB/3aO25LXPThwTvzkP3kyZOl7DLu26ShnUV/K89LpNUWyYMRr9KxfCW8RPJJY7OscSL5jIkgC4WzZMkST+Tjxo1rpdB27drl76Hwsihbef6kQJOUhvD5CZ96Y9EWydtS1e9+9zvJfcY6LUnuFZdfBETyGQ+Ieis68mPNHWuddfmk/Fmv5P6qVasS7yc9o7j2k1PSsBaO7ccxLWZG8n379nUTJkyIjiFDhngLHpmfOXOmZD5jnZYk94rLLwIi+YwHRFoFljYdX/RCmfXo0aOiMjNlOGzYsIpp0pandJVJK2lYC6/KeP1cbBYuXOhlH/mPH2zG0+767LAP+y5J7hWXXwRE8gUj+XCw6boxSq0SzknDulJaxV/evhL+9cM/Se4Vl18ERPIieVn7NcpA0rAWmdSPTIRlPrFMknvF5RcBkXyNCl4KKJ8KqJH9kjSsG1m+ypIMXg4ZSJJ7xeUXAZG8SF6WfI0ykDSsL4fSVZki+0bKQJLcKy6/CIjka1TwjRxUKiufSjxpWKuv8tlX6pf69UuS3CsuvwiI5EXysuRrlIGkYS0yqYYll0MAAAFwSURBVB+ZCMt8Ypkk94rLLwIi+RoVvBRQPhVQI/slaVg3snyVJRm8HDKQJPeKyy8CInmRvCz5GmUgaVhfDqWrMkX2jZSBJLlXXH4REMnXqOAbOahUVj6VeNKwVl/ls6/UL/XrlyS5V1x+ERDJi+RlydcoA0nDWmRSPzIRlvnEMknuFZdfBETyNSp4KaB8KqBG9kvSsG5k+SpLMng5ZCBJ7hWXXwRE8iJ5WfI1ykDSsL4cSldliuwbKQNJcq+4/CKQGcnnt8mqmRAQAkJACAiBciAgki9HP6uVQkAICAEhUEIERPIl7HQ1WQgIASEgBMqBgEi+HP2sVgoBISAEhEAJERDJl7DT1WQhIASEgBAoBwIi+XL0s1opBISAEBACJURAJF/CTleThYAQEAJCoBwIiOTL0c9qpRAQAkJACJQQAZF8CTtdTRYCQkAICIFyICCSL0c/q5VCQAgIASFQQgRE8iXsdDVZCAgBISAEyoHA/wMxnMxAlEsxAAAAAABJRU5ErkJggg==" %}

- -
-
-
-
-
-

Review the label result

-
-
-
- {% raw %} - -
-
- -
-
-
lbl.df.head()
-
- -
-
-
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
keywordlengthoptionslabel
0Appetite Regulation19[A, B]A
1Hymecromone11[A, B]B
2Round Ligament of Uterus24[A, B]A
3Sugar Acids11[A, B]B
4Nogalamycin11[A, B]B
-
-
- -
- -
-
- -
- {% endraw %} - -
-
-

Editable list and editable dict

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

class EditableList[source]

EditableList(*args, **kwargs) :: VBox

-
-

Interactive list -You can add item to the list -Each added item has a remove button to remove such item

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

class EditableDict[source]

EditableDict(*args, **kwargs) :: VBox

-
-

Interactive dictionary -You can add item to the dictionary -Each added item has a remove button to remove such item

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - -
-
-

Step by step

-
-
-
- {% raw %} - -
- -
-
- -
- - -
-

class LivingStep[source]

LivingStep(func:Callable, top_block:HTML=None)

-
-

A step interactive for StepByStep

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
-
- -
- - -
-

class StepByStep[source]

StepByStep(funcs:Dict[str, Callable], top_board:HTML=None, kwargs:Dict[str, Any]={})

-
-

A tool to manage progress step by step

- -
- -
- -
-
- -
- {% endraw %} - - {% raw %} - -
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
def test_step(**kwargs):
-    @interact
-    def show_step_(how_much=[1,2,4,8,16], charactor = ['🍺', '🏺', '🍶','🍷']):
-        return pd.DataFrame({"stuff":[charactor*how_much,]*how_much})
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
sbs = StepByStep(
-    {"step1":test_step,"some_step":test_step, "another_step":test_step},
-    HTML("""
-    <h1>Detail Steps</h1>
-    """)
-)
-
- -
-
-
- -
- {% endraw %} - - {% raw %} - -
-
- -
-
-
sbs()
-
- -
-
-
- -
- {% endraw %} - -
- - - - diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js deleted file mode 100644 index 27701a3..0000000 --- a/docs/js/customscripts.js +++ /dev/null @@ -1,54 +0,0 @@ -$('#mysidebar').height($(".nav").height()); - - -$( document ).ready(function() { - - //this script says, if the height of the viewport is greater than 800px, then insert affix class, which makes the nav bar float in a fixed - // position as your scroll. if you have a lot of nav items, this height may not work for you. - var h = $(window).height(); - //console.log (h); - if (h > 800) { - $( "#mysidebar" ).attr("class", "nav affix"); - } - // activate tooltips. although this is a bootstrap js function, it must be activated this way in your theme. - $('[data-toggle="tooltip"]').tooltip({ - placement : 'top' - }); - - /** - * AnchorJS - */ - anchors.add('h2,h3,h4,h5'); - -}); - -// needed for nav tabs on pages. See Formatting > Nav tabs for more details. -// script from http://stackoverflow.com/questions/10523433/how-do-i-keep-the-current-tab-active-with-twitter-bootstrap-after-a-page-reload -$(function() { - var json, tabsState; - $('a[data-toggle="pill"], a[data-toggle="tab"]').on('shown.bs.tab', function(e) { - var href, json, parentId, tabsState; - - tabsState = localStorage.getItem("tabs-state"); - json = JSON.parse(tabsState || "{}"); - parentId = $(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id"); - href = $(e.target).attr('href'); - json[parentId] = href; - - return localStorage.setItem("tabs-state", JSON.stringify(json)); - }); - - tabsState = localStorage.getItem("tabs-state"); - json = JSON.parse(tabsState || "{}"); - - $.each(json, function(containerId, href) { - return $("#" + containerId + " a[href=" + href + "]").tab('show'); - }); - - $("ul.nav.nav-pills, ul.nav.nav-tabs").each(function() { - var $this = $(this); - if (!json[$this.attr("id")]) { - return $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first").tab("show"); - } - }); -}); diff --git a/docs/js/jekyll-search.js b/docs/js/jekyll-search.js deleted file mode 100644 index d884a24..0000000 --- a/docs/js/jekyll-search.js +++ /dev/null @@ -1 +0,0 @@ -!function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o=0}var self=this;self.matches=function(string,crit){return"string"!=typeof string?!1:(string=string.trim(),doMatch(string,crit))}}module.exports=new LiteralSearchStrategy},{}],4:[function(require,module){module.exports=function(){function findMatches(store,crit,strategy){for(var data=store.get(),i=0;i{title}',noResultsText:"No results found",limit:10,fuzzy:!1};self.init=function(_opt){validateOptions(_opt),assignOptions(_opt),isJSON(opt.dataSource)?initWithJSON(opt.dataSource):initWithURL(opt.dataSource)}}var Searcher=require("./Searcher"),Templater=require("./Templater"),Store=require("./Store"),JSONLoader=require("./JSONLoader"),searcher=new Searcher,templater=new Templater,store=new Store,jsonLoader=new JSONLoader;window.SimpleJekyllSearch=new SimpleJekyllSearch}(window,document)},{"./JSONLoader":1,"./Searcher":4,"./Store":5,"./Templater":6}]},{},[7]); diff --git a/docs/js/jquery.ba-throttle-debounce.min.js b/docs/js/jquery.ba-throttle-debounce.min.js deleted file mode 100644 index 0720550..0000000 --- a/docs/js/jquery.ba-throttle-debounce.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/* - * jQuery throttle / debounce - v1.1 - 3/7/2010 - * http://benalman.com/projects/jquery-throttle-debounce-plugin/ - * - * Copyright (c) 2010 "Cowboy" Ben Alman - * Dual licensed under the MIT and GPL licenses. - * http://benalman.com/about/license/ - */ -(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this); \ No newline at end of file diff --git a/docs/js/jquery.navgoco.min.js b/docs/js/jquery.navgoco.min.js deleted file mode 100755 index 4ba4475..0000000 --- a/docs/js/jquery.navgoco.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/* - * jQuery Navgoco Menus Plugin v0.2.1 (2014-04-11) - * https://github.com/tefra/navgoco - * - * Copyright (c) 2014 Chris T (@tefra) - * BSD - https://github.com/tefra/navgoco/blob/master/LICENSE-BSD - */ -!function(a){"use strict";var b=function(b,c,d){return this.el=b,this.$el=a(b),this.options=c,this.uuid=this.$el.attr("id")?this.$el.attr("id"):d,this.state={},this.init(),this};b.prototype={init:function(){var b=this;b._load(),b.$el.find("ul").each(function(c){var d=a(this);d.attr("data-index",c),b.options.save&&b.state.hasOwnProperty(c)?(d.parent().addClass(b.options.openClass),d.show()):d.parent().hasClass(b.options.openClass)?(d.show(),b.state[c]=1):d.hide()});var c=a("").prepend(b.options.caretHtml),d=b.$el.find("li > a");b._trigger(c,!1),b._trigger(d,!0),b.$el.find("li:has(ul) > a").prepend(c)},_trigger:function(b,c){var d=this;b.on("click",function(b){b.stopPropagation();var e=c?a(this).next():a(this).parent().next(),f=!1;if(c){var g=a(this).attr("href");f=void 0===g||""===g||"#"===g}if(e=e.length>0?e:!1,d.options.onClickBefore.call(this,b,e),!c||e&&f)b.preventDefault(),d._toggle(e,e.is(":hidden")),d._save();else if(d.options.accordion){var h=d.state=d._parents(a(this));d.$el.find("ul").filter(":visible").each(function(){var b=a(this),c=b.attr("data-index");h.hasOwnProperty(c)||d._toggle(b,!1)}),d._save()}d.options.onClickAfter.call(this,b,e)})},_toggle:function(b,c){var d=this,e=b.attr("data-index"),f=b.parent();if(d.options.onToggleBefore.call(this,b,c),c){if(f.addClass(d.options.openClass),b.slideDown(d.options.slide),d.state[e]=1,d.options.accordion){var g=d.state=d._parents(b);g[e]=d.state[e]=1,d.$el.find("ul").filter(":visible").each(function(){var b=a(this),c=b.attr("data-index");g.hasOwnProperty(c)||d._toggle(b,!1)})}}else f.removeClass(d.options.openClass),b.slideUp(d.options.slide),d.state[e]=0;d.options.onToggleAfter.call(this,b,c)},_parents:function(b,c){var d={},e=b.parent(),f=e.parents("ul");return f.each(function(){var b=a(this),e=b.attr("data-index");return e?void(d[e]=c?b:1):!1}),d},_save:function(){if(this.options.save){var b={};for(var d in this.state)1===this.state[d]&&(b[d]=1);c[this.uuid]=this.state=b,a.cookie(this.options.cookie.name,JSON.stringify(c),this.options.cookie)}},_load:function(){if(this.options.save){if(null===c){var b=a.cookie(this.options.cookie.name);c=b?JSON.parse(b):{}}this.state=c.hasOwnProperty(this.uuid)?c[this.uuid]:{}}},toggle:function(b){var c=this,d=arguments.length;if(1>=d)c.$el.find("ul").each(function(){var d=a(this);c._toggle(d,b)});else{var e,f={},g=Array.prototype.slice.call(arguments,1);d--;for(var h=0;d>h;h++){e=g[h];var i=c.$el.find('ul[data-index="'+e+'"]').first();if(i&&(f[e]=i,b)){var j=c._parents(i,!0);for(var k in j)f.hasOwnProperty(k)||(f[k]=j[k])}}for(e in f)c._toggle(f[e],b)}c._save()},destroy:function(){a.removeData(this.$el),this.$el.find("li:has(ul) > a").unbind("click"),this.$el.find("li:has(ul) > a > span").unbind("click")}},a.fn.navgoco=function(c){if("string"==typeof c&&"_"!==c.charAt(0)&&"init"!==c)var d=!0,e=Array.prototype.slice.call(arguments,1);else c=a.extend({},a.fn.navgoco.defaults,c||{}),a.cookie||(c.save=!1);return this.each(function(f){var g=a(this),h=g.data("navgoco");h||(h=new b(this,d?a.fn.navgoco.defaults:c,f),g.data("navgoco",h)),d&&h[c].apply(h,e)})};var c=null;a.fn.navgoco.defaults={caretHtml:"",accordion:!1,openClass:"open",save:!0,cookie:{name:"navgoco",expires:!1,path:"/"},slide:{duration:400,easing:"swing"},onClickBefore:a.noop,onClickAfter:a.noop,onToggleBefore:a.noop,onToggleAfter:a.noop}}(jQuery); \ No newline at end of file diff --git a/docs/js/jquery.shuffle.min.js b/docs/js/jquery.shuffle.min.js deleted file mode 100644 index d103127..0000000 --- a/docs/js/jquery.shuffle.min.js +++ /dev/null @@ -1,1588 +0,0 @@ -/*! - * Shuffle.js by @Vestride - * Categorize, sort, and filter a responsive grid of items. - * Dependencies: jQuery 1.9+, Modernizr 2.6.2+ - * @license MIT license - * @version 3.0.0 - */ - -/* Modernizr 2.6.2 (Custom Build) | MIT & BSD - * Build: http://modernizr.com/download/#-csstransforms-csstransforms3d-csstransitions-cssclasses-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes - */ -window.Modernizr=function(a,b,c){function z(a){j.cssText=a}function A(a,b){return z(m.join(a+";")+(b||""))}function B(a,b){return typeof a===b}function C(a,b){return!!~(""+a).indexOf(b)}function D(a,b){for(var d in a){var e=a[d];if(!C(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function E(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:B(f,"function")?f.bind(d||b):f}return!1}function F(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+o.join(d+" ")+d).split(" ");return B(b,"string")||B(b,"undefined")?D(e,b):(e=(a+" "+p.join(d+" ")+d).split(" "),E(e,b,c))}var d="2.6.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n="Webkit Moz O ms",o=n.split(" "),p=n.toLowerCase().split(" "),q={},r={},s={},t=[],u=t.slice,v,w=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["­",'"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},x={}.hasOwnProperty,y;!B(x,"undefined")&&!B(x.call,"undefined")?y=function(a,b){return x.call(a,b)}:y=function(a,b){return b in a&&B(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=u.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(u.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(u.call(arguments)))};return e}),q.csstransforms=function(){return!!F("transform")},q.csstransforms3d=function(){var a=!!F("perspective");return a&&"webkitPerspective"in g.style&&w("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},q.csstransitions=function(){return F("transition")};for(var G in q)y(q,G)&&(v=G.toLowerCase(),e[v]=q[G](),t.push((e[v]?"":"no-")+v));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)y(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},z(""),i=k=null,e._version=d,e._prefixes=m,e._domPrefixes=p,e._cssomPrefixes=o,e.testProp=function(a){return D([a])},e.testAllProps=F,e.testStyles=w,e.prefixed=function(a,b,c){return b?F(a,b,c):F(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+t.join(" "):""),e}(this,this.document); - -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['jquery', 'modernizr'], factory); - } else { - window.Shuffle = factory(window.jQuery, window.Modernizr); - } -})(function($, Modernizr, undefined) { - -'use strict'; - - -// Validate Modernizr exists. -// Shuffle requires `csstransitions`, `csstransforms`, `csstransforms3d`, -// and `prefixed` to exist on the Modernizr object. -if (typeof Modernizr !== 'object') { - throw new Error('Shuffle.js requires Modernizr.\n' + - 'http://vestride.github.io/Shuffle/#dependencies'); -} - - -/** - * Returns css prefixed properties like `-webkit-transition` or `box-sizing` - * from `transition` or `boxSizing`, respectively. - * @param {(string|boolean)} prop Property to be prefixed. - * @return {string} The prefixed css property. - */ -function dashify( prop ) { - if (!prop) { - return ''; - } - - // Replace upper case with dash-lowercase, - // then fix ms- prefixes because they're not capitalized. - return prop.replace(/([A-Z])/g, function( str, m1 ) { - return '-' + m1.toLowerCase(); - }).replace(/^ms-/,'-ms-'); -} - -// Constant, prefixed variables. -var TRANSITION = Modernizr.prefixed('transition'); -var TRANSITION_DELAY = Modernizr.prefixed('transitionDelay'); -var TRANSITION_DURATION = Modernizr.prefixed('transitionDuration'); - -// Note(glen): Stock Android 4.1.x browser will fail here because it wrongly -// says it supports non-prefixed transitions. -// https://github.com/Modernizr/Modernizr/issues/897 -var TRANSITIONEND = { - 'WebkitTransition' : 'webkitTransitionEnd', - 'transition' : 'transitionend' -}[ TRANSITION ]; - -var TRANSFORM = Modernizr.prefixed('transform'); -var CSS_TRANSFORM = dashify(TRANSFORM); - -// Constants -var CAN_TRANSITION_TRANSFORMS = Modernizr.csstransforms && Modernizr.csstransitions; -var HAS_TRANSFORMS_3D = Modernizr.csstransforms3d; -var SHUFFLE = 'shuffle'; -var COLUMN_THRESHOLD = 0.3; - -// Configurable. You can change these constants to fit your application. -// The default scale and concealed scale, however, have to be different values. -var ALL_ITEMS = 'all'; -var FILTER_ATTRIBUTE_KEY = 'groups'; -var DEFAULT_SCALE = 1; -var CONCEALED_SCALE = 0.001; - - -// Underscore's throttle function. -function throttle(func, wait, options) { - var context, args, result; - var timeout = null; - var previous = 0; - options = options || {}; - var later = function() { - previous = options.leading === false ? 0 : $.now(); - timeout = null; - result = func.apply(context, args); - context = args = null; - }; - return function() { - var now = $.now(); - if (!previous && options.leading === false) { - previous = now; - } - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0 || remaining > wait) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); - } - return result; - }; -} - -function each(obj, iterator, context) { - for (var i = 0, length = obj.length; i < length; i++) { - if (iterator.call(context, obj[i], i, obj) === {}) { - return; - } - } -} - -function defer(fn, context, wait) { - return setTimeout( $.proxy( fn, context ), wait ); -} - -function arrayMax( array ) { - return Math.max.apply( Math, array ); -} - -function arrayMin( array ) { - return Math.min.apply( Math, array ); -} - - -/** - * Always returns a numeric value, given a value. - * @param {*} value Possibly numeric value. - * @return {number} `value` or zero if `value` isn't numeric. - * @private - */ -function getNumber(value) { - return $.isNumeric(value) ? value : 0; -} - - -/** - * Represents a coordinate pair. - * @param {number} [x=0] X. - * @param {number} [y=0] Y. - */ -var Point = function(x, y) { - this.x = getNumber( x ); - this.y = getNumber( y ); -}; - - -/** - * Whether two points are equal. - * @param {Point} a Point A. - * @param {Point} b Point B. - * @return {boolean} - */ -Point.equals = function(a, b) { - return a.x === b.x && a.y === b.y; -}; - - -// Used for unique instance variables -var id = 0; -var $window = $( window ); - - -/** - * Categorize, sort, and filter a responsive grid of items. - * - * @param {Element} element An element which is the parent container for the grid items. - * @param {Object} [options=Shuffle.options] Options object. - * @constructor - */ -var Shuffle = function( element, options ) { - options = options || {}; - $.extend( this, Shuffle.options, options, Shuffle.settings ); - - this.$el = $(element); - this.element = element; - this.unique = 'shuffle_' + id++; - - this._fire( Shuffle.EventType.LOADING ); - this._init(); - - // Dispatch the done event asynchronously so that people can bind to it after - // Shuffle has been initialized. - defer(function() { - this.initialized = true; - this._fire( Shuffle.EventType.DONE ); - }, this, 16); -}; - - -/** - * Events the container element emits with the .shuffle namespace. - * For example, "done.shuffle". - * @enum {string} - */ -Shuffle.EventType = { - LOADING: 'loading', - DONE: 'done', - LAYOUT: 'layout', - REMOVED: 'removed' -}; - - -/** @enum {string} */ -Shuffle.ClassName = { - BASE: SHUFFLE, - SHUFFLE_ITEM: 'shuffle-item', - FILTERED: 'filtered', - CONCEALED: 'concealed' -}; - - -// Overrideable options -Shuffle.options = { - group: ALL_ITEMS, // Initial filter group. - speed: 250, // Transition/animation speed (milliseconds). - easing: 'ease-out', // CSS easing function to use. - itemSelector: '', // e.g. '.picture-item'. - sizer: null, // Sizer element. Use an element to determine the size of columns and gutters. - gutterWidth: 0, // A static number or function that tells the plugin how wide the gutters between columns are (in pixels). - columnWidth: 0, // A static number or function that returns a number which tells the plugin how wide the columns are (in pixels). - delimeter: null, // If your group is not json, and is comma delimeted, you could set delimeter to ','. - buffer: 0, // Useful for percentage based heights when they might not always be exactly the same (in pixels). - initialSort: null, // Shuffle can be initialized with a sort object. It is the same object given to the sort method. - throttle: throttle, // By default, shuffle will throttle resize events. This can be changed or removed. - throttleTime: 300, // How often shuffle can be called on resize (in milliseconds). - sequentialFadeDelay: 150, // Delay between each item that fades in when adding items. - supported: CAN_TRANSITION_TRANSFORMS // Whether to use transforms or absolute positioning. -}; - - -// Not overrideable -Shuffle.settings = { - useSizer: false, - itemCss : { // default CSS for each item - position: 'absolute', - top: 0, - left: 0, - visibility: 'visible' - }, - revealAppendedDelay: 300, - lastSort: {}, - lastFilter: ALL_ITEMS, - enabled: true, - destroyed: false, - initialized: false, - _animations: [], - styleQueue: [] -}; - - -// Expose for testing. -Shuffle.Point = Point; - - -/** - * Static methods. - */ - -/** - * If the browser has 3d transforms available, build a string with those, - * otherwise use 2d transforms. - * @param {Point} point X and Y positions. - * @param {number} scale Scale amount. - * @return {string} A normalized string which can be used with the transform style. - * @private - */ -Shuffle._getItemTransformString = function(point, scale) { - if ( HAS_TRANSFORMS_3D ) { - return 'translate3d(' + point.x + 'px, ' + point.y + 'px, 0) scale3d(' + scale + ', ' + scale + ', 1)'; - } else { - return 'translate(' + point.x + 'px, ' + point.y + 'px) scale(' + scale + ')'; - } -}; - - -/** - * Retrieve the computed style for an element, parsed as a float. This should - * not be used for width or height values because jQuery mangles them and they - * are not precise enough. - * @param {Element} element Element to get style for. - * @param {string} style Style property. - * @return {number} The parsed computed value or zero if that fails because IE - * will return 'auto' when the element doesn't have margins instead of - * the computed style. - * @private - */ -Shuffle._getNumberStyle = function( element, style ) { - return Shuffle._getFloat( $( element ).css( style ) ); -}; - - -/** - * Parse a string as an integer. - * @param {string} value String integer. - * @return {number} The string as an integer or zero. - * @private - */ -Shuffle._getInt = function(value) { - return getNumber( parseInt( value, 10 ) ); -}; - -/** - * Parse a string as an float. - * @param {string} value String float. - * @return {number} The string as an float or zero. - * @private - */ -Shuffle._getFloat = function(value) { - return getNumber( parseFloat( value ) ); -}; - - -/** - * Returns the outer width of an element, optionally including its margins. - * The `offsetWidth` property must be used because having a scale transform - * on the element affects the bounding box. Sadly, Firefox doesn't return an - * integer value for offsetWidth (yet). - * @param {Element} element The element. - * @param {boolean} [includeMargins] Whether to include margins. Default is false. - * @return {number} The width. - */ -Shuffle._getOuterWidth = function( element, includeMargins ) { - var width = element.offsetWidth; - - // Use jQuery here because it uses getComputedStyle internally and is - // cross-browser. Using the style property of the element will only work - // if there are inline styles. - if ( includeMargins ) { - var marginLeft = Shuffle._getNumberStyle( element, 'marginLeft'); - var marginRight = Shuffle._getNumberStyle( element, 'marginRight'); - width += marginLeft + marginRight; - } - - return width; -}; - - -/** - * Returns the outer height of an element, optionally including its margins. - * @param {Element} element The element. - * @param {boolean} [includeMargins] Whether to include margins. Default is false. - * @return {number} The height. - */ -Shuffle._getOuterHeight = function( element, includeMargins ) { - var height = element.offsetHeight; - - if ( includeMargins ) { - var marginTop = Shuffle._getNumberStyle( element, 'marginTop'); - var marginBottom = Shuffle._getNumberStyle( element, 'marginBottom'); - height += marginTop + marginBottom; - } - - return height; -}; - - -/** - * Change a property or execute a function which will not have a transition - * @param {Element} element DOM element that won't be transitioned - * @param {Function} callback A function which will be called while transition - * is set to 0ms. - * @param {Object} [context] Optional context for the callback function. - * @private - */ -Shuffle._skipTransition = function( element, callback, context ) { - var duration = element.style[ TRANSITION_DURATION ]; - - // Set the duration to zero so it happens immediately - element.style[ TRANSITION_DURATION ] = '0ms'; // ms needed for firefox! - - callback.call( context ); - - // Force reflow - var reflow = element.offsetWidth; - // Avoid jshint warnings: unused variables and expressions. - reflow = null; - - // Put the duration back - element.style[ TRANSITION_DURATION ] = duration; -}; - - -/** - * Instance methods. - */ - -Shuffle.prototype._init = function() { - this.$items = this._getItems(); - - this.sizer = this._getElementOption( this.sizer ); - - if ( this.sizer ) { - this.useSizer = true; - } - - // Add class and invalidate styles - this.$el.addClass( Shuffle.ClassName.BASE ); - - // Set initial css for each item - this._initItems(); - - // Bind resize events - // http://stackoverflow.com/questions/1852751/window-resize-event-firing-in-internet-explorer - $window.on('resize.' + SHUFFLE + '.' + this.unique, this._getResizeFunction()); - - // Get container css all in one request. Causes reflow - var containerCSS = this.$el.css(['position', 'overflow']); - var containerWidth = Shuffle._getOuterWidth( this.element ); - - // Add styles to the container if it doesn't have them. - this._validateStyles( containerCSS ); - - // We already got the container's width above, no need to cause another reflow getting it again... - // Calculate the number of columns there will be - this._setColumns( containerWidth ); - - // Kick off! - this.shuffle( this.group, this.initialSort ); - - // The shuffle items haven't had transitions set on them yet - // so the user doesn't see the first layout. Set them now that the first layout is done. - if ( this.supported ) { - defer(function() { - this._setTransitions(); - this.element.style[ TRANSITION ] = 'height ' + this.speed + 'ms ' + this.easing; - }, this); - } -}; - - -/** - * Returns a throttled and proxied function for the resize handler. - * @return {Function} - * @private - */ -Shuffle.prototype._getResizeFunction = function() { - var resizeFunction = $.proxy( this._onResize, this ); - return this.throttle ? - this.throttle( resizeFunction, this.throttleTime ) : - resizeFunction; -}; - - -/** - * Retrieve an element from an option. - * @param {string|jQuery|Element} option The option to check. - * @return {?Element} The plain element or null. - * @private - */ -Shuffle.prototype._getElementOption = function( option ) { - // If column width is a string, treat is as a selector and search for the - // sizer element within the outermost container - if ( typeof option === 'string' ) { - return this.$el.find( option )[0] || null; - - // Check for an element - } else if ( option && option.nodeType && option.nodeType === 1 ) { - return option; - - // Check for jQuery object - } else if ( option && option.jquery ) { - return option[0]; - } - - return null; -}; - - -/** - * Ensures the shuffle container has the css styles it needs applied to it. - * @param {Object} styles Key value pairs for position and overflow. - * @private - */ -Shuffle.prototype._validateStyles = function(styles) { - // Position cannot be static. - if ( styles.position === 'static' ) { - this.element.style.position = 'relative'; - } - - // Overflow has to be hidden - if ( styles.overflow !== 'hidden' ) { - this.element.style.overflow = 'hidden'; - } -}; - - -/** - * Filter the elements by a category. - * @param {string} [category] Category to filter by. If it's given, the last - * category will be used to filter the items. - * @param {ArrayLike} [$collection] Optionally filter a collection. Defaults to - * all the items. - * @return {jQuery} Filtered items. - * @private - */ -Shuffle.prototype._filter = function( category, $collection ) { - category = category || this.lastFilter; - $collection = $collection || this.$items; - - var set = this._getFilteredSets( category, $collection ); - - // Individually add/remove concealed/filtered classes - this._toggleFilterClasses( set.filtered, set.concealed ); - - // Save the last filter in case elements are appended. - this.lastFilter = category; - - // This is saved mainly because providing a filter function (like searching) - // will overwrite the `lastFilter` property every time its called. - if ( typeof category === 'string' ) { - this.group = category; - } - - return set.filtered; -}; - - -/** - * Returns an object containing the filtered and concealed elements. - * @param {string|Function} category Category or function to filter by. - * @param {ArrayLike.} $items A collection of items to filter. - * @return {!{filtered: jQuery, concealed: jQuery}} - * @private - */ -Shuffle.prototype._getFilteredSets = function( category, $items ) { - var $filtered = $(); - var $concealed = $(); - - // category === 'all', add filtered class to everything - if ( category === ALL_ITEMS ) { - $filtered = $items; - - // Loop through each item and use provided function to determine - // whether to hide it or not. - } else { - each($items, function( el ) { - var $item = $(el); - if ( this._doesPassFilter( category, $item ) ) { - $filtered = $filtered.add( $item ); - } else { - $concealed = $concealed.add( $item ); - } - }, this); - } - - return { - filtered: $filtered, - concealed: $concealed - }; -}; - - -/** - * Test an item to see if it passes a category. - * @param {string|Function} category Category or function to filter by. - * @param {jQuery} $item A single item, wrapped with jQuery. - * @return {boolean} Whether it passes the category/filter. - * @private - */ -Shuffle.prototype._doesPassFilter = function( category, $item ) { - if ( $.isFunction( category ) ) { - return category.call( $item[0], $item, this ); - - // Check each element's data-groups attribute against the given category. - } else { - var groups = $item.data( FILTER_ATTRIBUTE_KEY ); - var keys = this.delimeter && !$.isArray( groups ) ? - groups.split( this.delimeter ) : - groups; - return $.inArray(category, keys) > -1; - } -}; - - -/** - * Toggles the filtered and concealed class names. - * @param {jQuery} $filtered Filtered set. - * @param {jQuery} $concealed Concealed set. - * @private - */ -Shuffle.prototype._toggleFilterClasses = function( $filtered, $concealed ) { - $filtered - .removeClass( Shuffle.ClassName.CONCEALED ) - .addClass( Shuffle.ClassName.FILTERED ); - $concealed - .removeClass( Shuffle.ClassName.FILTERED ) - .addClass( Shuffle.ClassName.CONCEALED ); -}; - - -/** - * Set the initial css for each item - * @param {jQuery} [$items] Optionally specifiy at set to initialize - */ -Shuffle.prototype._initItems = function( $items ) { - $items = $items || this.$items; - $items.addClass([ - Shuffle.ClassName.SHUFFLE_ITEM, - Shuffle.ClassName.FILTERED - ].join(' ')); - $items.css( this.itemCss ).data('point', new Point()).data('scale', DEFAULT_SCALE); -}; - - -/** - * Updates the filtered item count. - * @private - */ -Shuffle.prototype._updateItemCount = function() { - this.visibleItems = this._getFilteredItems().length; -}; - - -/** - * Sets css transform transition on a an element. - * @param {Element} element Element to set transition on. - * @private - */ -Shuffle.prototype._setTransition = function( element ) { - element.style[ TRANSITION ] = CSS_TRANSFORM + ' ' + this.speed + 'ms ' + - this.easing + ', opacity ' + this.speed + 'ms ' + this.easing; -}; - - -/** - * Sets css transform transition on a group of elements. - * @param {ArrayLike.} $items Elements to set transitions on. - * @private - */ -Shuffle.prototype._setTransitions = function( $items ) { - $items = $items || this.$items; - each($items, function( el ) { - this._setTransition( el ); - }, this); -}; - - -/** - * Sets a transition delay on a collection of elements, making each delay - * greater than the last. - * @param {ArrayLike.} $collection Array to iterate over. - */ -Shuffle.prototype._setSequentialDelay = function( $collection ) { - if ( !this.supported ) { - return; - } - - // $collection can be an array of dom elements or jquery object - each($collection, function( el, i ) { - // This works because the transition-property: transform, opacity; - el.style[ TRANSITION_DELAY ] = '0ms,' + ((i + 1) * this.sequentialFadeDelay) + 'ms'; - }, this); -}; - - -Shuffle.prototype._getItems = function() { - return this.$el.children( this.itemSelector ); -}; - - -Shuffle.prototype._getFilteredItems = function() { - return this.$items.filter('.' + Shuffle.ClassName.FILTERED); -}; - - -Shuffle.prototype._getConcealedItems = function() { - return this.$items.filter('.' + Shuffle.ClassName.CONCEALED); -}; - - -/** - * Returns the column size, based on column width and sizer options. - * @param {number} containerWidth Size of the parent container. - * @param {number} gutterSize Size of the gutters. - * @return {number} - * @private - */ -Shuffle.prototype._getColumnSize = function( containerWidth, gutterSize ) { - var size; - - // If the columnWidth property is a function, then the grid is fluid - if ( $.isFunction( this.columnWidth ) ) { - size = this.columnWidth(containerWidth); - - // columnWidth option isn't a function, are they using a sizing element? - } else if ( this.useSizer ) { - size = Shuffle._getOuterWidth(this.sizer); - - // if not, how about the explicitly set option? - } else if ( this.columnWidth ) { - size = this.columnWidth; - - // or use the size of the first item - } else if ( this.$items.length > 0 ) { - size = Shuffle._getOuterWidth(this.$items[0], true); - - // if there's no items, use size of container - } else { - size = containerWidth; - } - - // Don't let them set a column width of zero. - if ( size === 0 ) { - size = containerWidth; - } - - return size + gutterSize; -}; - - -/** - * Returns the gutter size, based on gutter width and sizer options. - * @param {number} containerWidth Size of the parent container. - * @return {number} - * @private - */ -Shuffle.prototype._getGutterSize = function( containerWidth ) { - var size; - if ( $.isFunction( this.gutterWidth ) ) { - size = this.gutterWidth(containerWidth); - } else if ( this.useSizer ) { - size = Shuffle._getNumberStyle(this.sizer, 'marginLeft'); - } else { - size = this.gutterWidth; - } - - return size; -}; - - -/** - * Calculate the number of columns to be used. Gets css if using sizer element. - * @param {number} [theContainerWidth] Optionally specify a container width if it's already available. - */ -Shuffle.prototype._setColumns = function( theContainerWidth ) { - var containerWidth = theContainerWidth || Shuffle._getOuterWidth( this.element ); - var gutter = this._getGutterSize( containerWidth ); - var columnWidth = this._getColumnSize( containerWidth, gutter ); - var calculatedColumns = (containerWidth + gutter) / columnWidth; - - // Widths given from getComputedStyle are not precise enough... - if ( Math.abs(Math.round(calculatedColumns) - calculatedColumns) < COLUMN_THRESHOLD ) { - // e.g. calculatedColumns = 11.998876 - calculatedColumns = Math.round( calculatedColumns ); - } - - this.cols = Math.max( Math.floor(calculatedColumns), 1 ); - this.containerWidth = containerWidth; - this.colWidth = columnWidth; -}; - -/** - * Adjust the height of the grid - */ -Shuffle.prototype._setContainerSize = function() { - this.$el.css( 'height', this._getContainerSize() ); -}; - - -/** - * Based on the column heights, it returns the biggest one. - * @return {number} - * @private - */ -Shuffle.prototype._getContainerSize = function() { - return arrayMax( this.positions ); -}; - - -/** - * Fire events with .shuffle namespace - */ -Shuffle.prototype._fire = function( name, args ) { - this.$el.trigger( name + '.' + SHUFFLE, args && args.length ? args : [ this ] ); -}; - - -/** - * Zeros out the y columns array, which is used to determine item placement. - * @private - */ -Shuffle.prototype._resetCols = function() { - var i = this.cols; - this.positions = []; - while (i--) { - this.positions.push( 0 ); - } -}; - - -/** - * Loops through each item that should be shown and calculates the x, y position. - * @param {Array.} items Array of items that will be shown/layed out in order in their array. - * Because jQuery collection are always ordered in DOM order, we can't pass a jq collection. - * @param {boolean} [isOnlyPosition=false] If true this will position the items with zero opacity. - */ -Shuffle.prototype._layout = function( items, isOnlyPosition ) { - each(items, function( item ) { - this._layoutItem( item, !!isOnlyPosition ); - }, this); - - // `_layout` always happens after `_shrink`, so it's safe to process the style - // queue here with styles from the shrink method. - this._processStyleQueue(); - - // Adjust the height of the container. - this._setContainerSize(); -}; - - -/** - * Calculates the position of the item and pushes it onto the style queue. - * @param {Element} item Element which is being positioned. - * @param {boolean} isOnlyPosition Whether to position the item, but with zero - * opacity so that it can fade in later. - * @private - */ -Shuffle.prototype._layoutItem = function( item, isOnlyPosition ) { - var $item = $(item); - var itemData = $item.data(); - var currPos = itemData.point; - var currScale = itemData.scale; - var itemSize = { - width: Shuffle._getOuterWidth( item, true ), - height: Shuffle._getOuterHeight( item, true ) - }; - var pos = this._getItemPosition( itemSize ); - - // If the item will not change its position, do not add it to the render - // queue. Transitions don't fire when setting a property to the same value. - if ( Point.equals(currPos, pos) && currScale === DEFAULT_SCALE ) { - return; - } - - // Save data for shrink - itemData.point = pos; - itemData.scale = DEFAULT_SCALE; - - this.styleQueue.push({ - $item: $item, - point: pos, - scale: DEFAULT_SCALE, - opacity: isOnlyPosition ? 0 : 1, - skipTransition: isOnlyPosition, - callfront: function() { - if ( !isOnlyPosition ) { - $item.css( 'visibility', 'visible' ); - } - }, - callback: function() { - if ( isOnlyPosition ) { - $item.css( 'visibility', 'hidden' ); - } - } - }); -}; - - -/** - * Determine the location of the next item, based on its size. - * @param {{width: number, height: number}} itemSize Object with width and height. - * @return {Point} - * @private - */ -Shuffle.prototype._getItemPosition = function( itemSize ) { - var columnSpan = this._getColumnSpan( itemSize.width, this.colWidth, this.cols ); - - var setY = this._getColumnSet( columnSpan, this.cols ); - - // Finds the index of the smallest number in the set. - var shortColumnIndex = this._getShortColumn( setY, this.buffer ); - - // Position the item - var point = new Point( - Math.round( this.colWidth * shortColumnIndex ), - Math.round( setY[shortColumnIndex] )); - - // Update the columns array with the new values for each column. - // e.g. before the update the columns could be [250, 0, 0, 0] for an item - // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0]. - var setHeight = setY[shortColumnIndex] + itemSize.height; - var setSpan = this.cols + 1 - setY.length; - for ( var i = 0; i < setSpan; i++ ) { - this.positions[ shortColumnIndex + i ] = setHeight; - } - - return point; -}; - - -/** - * Determine the number of columns an items spans. - * @param {number} itemWidth Width of the item. - * @param {number} columnWidth Width of the column (includes gutter). - * @param {number} columns Total number of columns - * @return {number} - * @private - */ -Shuffle.prototype._getColumnSpan = function( itemWidth, columnWidth, columns ) { - var columnSpan = itemWidth / columnWidth; - - // If the difference between the rounded column span number and the - // calculated column span number is really small, round the number to - // make it fit. - if ( Math.abs(Math.round( columnSpan ) - columnSpan ) < COLUMN_THRESHOLD ) { - // e.g. columnSpan = 4.0089945390298745 - columnSpan = Math.round( columnSpan ); - } - - // Ensure the column span is not more than the amount of columns in the whole layout. - return Math.min( Math.ceil( columnSpan ), columns ); -}; - - -/** - * Retrieves the column set to use for placement. - * @param {number} columnSpan The number of columns this current item spans. - * @param {number} columns The total columns in the grid. - * @return {Array.} An array of numbers represeting the column set. - * @private - */ -Shuffle.prototype._getColumnSet = function( columnSpan, columns ) { - // The item spans only one column. - if ( columnSpan === 1 ) { - return this.positions; - - // The item spans more than one column, figure out how many different - // places it could fit horizontally. - // The group count is the number of places within the positions this block - // could fit, ignoring the current positions of items. - // Imagine a 2 column brick as the second item in a 4 column grid with - // 10px height each. Find the places it would fit: - // [10, 0, 0, 0] - // | | | - // * * * - // - // Then take the places which fit and get the bigger of the two: - // max([10, 0]), max([0, 0]), max([0, 0]) = [10, 0, 0] - // - // Next, find the first smallest number (the short column). - // [10, 0, 0] - // | - // * - // - // And that's where it should be placed! - } else { - var groupCount = columns + 1 - columnSpan; - var groupY = []; - - // For how many possible positions for this item there are. - for ( var i = 0; i < groupCount; i++ ) { - // Find the bigger value for each place it could fit. - groupY[i] = arrayMax( this.positions.slice( i, i + columnSpan ) ); - } - - return groupY; - } -}; - - -/** - * Find index of short column, the first from the left where this item will go. - * - * @param {Array.} positions The array to search for the smallest number. - * @param {number} buffer Optional buffer which is very useful when the height - * is a percentage of the width. - * @return {number} Index of the short column. - * @private - */ -Shuffle.prototype._getShortColumn = function( positions, buffer ) { - var minPosition = arrayMin( positions ); - for (var i = 0, len = positions.length; i < len; i++) { - if ( positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer ) { - return i; - } - } - return 0; -}; - - -/** - * Hides the elements that don't match our filter. - * @param {jQuery} $collection jQuery collection to shrink. - * @private - */ -Shuffle.prototype._shrink = function( $collection ) { - var $concealed = $collection || this._getConcealedItems(); - - each($concealed, function( item ) { - var $item = $(item); - var itemData = $item.data(); - - // Continuing would add a transitionend event listener to the element, but - // that listener would not execute because the transform and opacity would - // stay the same. - if ( itemData.scale === CONCEALED_SCALE ) { - return; - } - - itemData.scale = CONCEALED_SCALE; - - this.styleQueue.push({ - $item: $item, - point: itemData.point, - scale : CONCEALED_SCALE, - opacity: 0, - callback: function() { - $item.css( 'visibility', 'hidden' ); - } - }); - }, this); -}; - - -/** - * Resize handler. - * @private - */ -Shuffle.prototype._onResize = function() { - // If shuffle is disabled, destroyed, don't do anything - if ( !this.enabled || this.destroyed || this.isTransitioning ) { - return; - } - - // Will need to check height in the future if it's layed out horizontaly - var containerWidth = Shuffle._getOuterWidth( this.element ); - - // containerWidth hasn't changed, don't do anything - if ( containerWidth === this.containerWidth ) { - return; - } - - this.update(); -}; - - -/** - * Returns styles for either jQuery animate or transition. - * @param {Object} opts Transition options. - * @return {!Object} Transforms for transitions, left/top for animate. - * @private - */ -Shuffle.prototype._getStylesForTransition = function( opts ) { - var styles = { - opacity: opts.opacity - }; - - if ( this.supported ) { - styles[ TRANSFORM ] = Shuffle._getItemTransformString( opts.point, opts.scale ); - } else { - styles.left = opts.point.x; - styles.top = opts.point.y; - } - - return styles; -}; - - -/** - * Transitions an item in the grid - * - * @param {Object} opts options. - * @param {jQuery} opts.$item jQuery object representing the current item. - * @param {Point} opts.point A point object with the x and y coordinates. - * @param {number} opts.scale Amount to scale the item. - * @param {number} opts.opacity Opacity of the item. - * @param {Function} opts.callback Complete function for the animation. - * @param {Function} opts.callfront Function to call before transitioning. - * @private - */ -Shuffle.prototype._transition = function( opts ) { - var styles = this._getStylesForTransition( opts ); - this._startItemAnimation( opts.$item, styles, opts.callfront || $.noop, opts.callback || $.noop ); -}; - - -Shuffle.prototype._startItemAnimation = function( $item, styles, callfront, callback ) { - // Transition end handler removes its listener. - function handleTransitionEnd( evt ) { - // Make sure this event handler has not bubbled up from a child. - if ( evt.target === evt.currentTarget ) { - $( evt.target ).off( TRANSITIONEND, handleTransitionEnd ); - callback(); - } - } - - callfront(); - - // Transitions are not set until shuffle has loaded to avoid the initial transition. - if ( !this.initialized ) { - $item.css( styles ); - callback(); - return; - } - - // Use CSS Transforms if we have them - if ( this.supported ) { - $item.css( styles ); - $item.on( TRANSITIONEND, handleTransitionEnd ); - - // Use jQuery to animate left/top - } else { - // Save the deferred object which jQuery returns. - var anim = $item.stop( true ).animate( styles, this.speed, 'swing', callback ); - // Push the animation to the list of pending animations. - this._animations.push( anim.promise() ); - } -}; - - -/** - * Execute the styles gathered in the style queue. This applies styles to elements, - * triggering transitions. - * @param {boolean} noLayout Whether to trigger a layout event. - * @private - */ -Shuffle.prototype._processStyleQueue = function( noLayout ) { - var $transitions = $(); - - // Iterate over the queue and keep track of ones that use transitions. - each(this.styleQueue, function( transitionObj ) { - if ( transitionObj.skipTransition ) { - this._styleImmediately( transitionObj ); - } else { - $transitions = $transitions.add( transitionObj.$item ); - this._transition( transitionObj ); - } - }, this); - - - if ( $transitions.length > 0 && this.initialized ) { - // Set flag that shuffle is currently in motion. - this.isTransitioning = true; - - if ( this.supported ) { - this._whenCollectionDone( $transitions, TRANSITIONEND, this._movementFinished ); - - // The _transition function appends a promise to the animations array. - // When they're all complete, do things. - } else { - this._whenAnimationsDone( this._movementFinished ); - } - - // A call to layout happened, but none of the newly filtered items will - // change position. Asynchronously fire the callback here. - } else if ( !noLayout ) { - defer( this._layoutEnd, this ); - } - - // Remove everything in the style queue - this.styleQueue.length = 0; -}; - - -/** - * Apply styles without a transition. - * @param {Object} opts Transitions options object. - * @private - */ -Shuffle.prototype._styleImmediately = function( opts ) { - Shuffle._skipTransition(opts.$item[0], function() { - opts.$item.css( this._getStylesForTransition( opts ) ); - }, this); -}; - -Shuffle.prototype._movementFinished = function() { - this.isTransitioning = false; - this._layoutEnd(); -}; - -Shuffle.prototype._layoutEnd = function() { - this._fire( Shuffle.EventType.LAYOUT ); -}; - -Shuffle.prototype._addItems = function( $newItems, addToEnd, isSequential ) { - // Add classes and set initial positions. - this._initItems( $newItems ); - - // Add transition to each item. - this._setTransitions( $newItems ); - - // Update the list of - this.$items = this._getItems(); - - // Shrink all items (without transitions). - this._shrink( $newItems ); - each(this.styleQueue, function( transitionObj ) { - transitionObj.skipTransition = true; - }); - - // Apply shrink positions, but do not cause a layout event. - this._processStyleQueue( true ); - - if ( addToEnd ) { - this._addItemsToEnd( $newItems, isSequential ); - } else { - this.shuffle( this.lastFilter ); - } -}; - - -Shuffle.prototype._addItemsToEnd = function( $newItems, isSequential ) { - // Get ones that passed the current filter - var $passed = this._filter( null, $newItems ); - var passed = $passed.get(); - - // How many filtered elements? - this._updateItemCount(); - - this._layout( passed, true ); - - if ( isSequential && this.supported ) { - this._setSequentialDelay( passed ); - } - - this._revealAppended( passed ); -}; - - -/** - * Triggers appended elements to fade in. - * @param {ArrayLike.} $newFilteredItems Collection of elements. - * @private - */ -Shuffle.prototype._revealAppended = function( newFilteredItems ) { - defer(function() { - each(newFilteredItems, function( el ) { - var $item = $( el ); - this._transition({ - $item: $item, - opacity: 1, - point: $item.data('point'), - scale: DEFAULT_SCALE - }); - }, this); - - this._whenCollectionDone($(newFilteredItems), TRANSITIONEND, function() { - $(newFilteredItems).css( TRANSITION_DELAY, '0ms' ); - this._movementFinished(); - }); - }, this, this.revealAppendedDelay); -}; - - -/** - * Execute a function when an event has been triggered for every item in a collection. - * @param {jQuery} $collection Collection of elements. - * @param {string} eventName Event to listen for. - * @param {Function} callback Callback to execute when they're done. - * @private - */ -Shuffle.prototype._whenCollectionDone = function( $collection, eventName, callback ) { - var done = 0; - var items = $collection.length; - var self = this; - - function handleEventName( evt ) { - if ( evt.target === evt.currentTarget ) { - $( evt.target ).off( eventName, handleEventName ); - done++; - - // Execute callback if all items have emitted the correct event. - if ( done === items ) { - callback.call( self ); - } - } - } - - // Bind the event to all items. - $collection.on( eventName, handleEventName ); -}; - - -/** - * Execute a callback after jQuery `animate` for a collection has finished. - * @param {Function} callback Callback to execute when they're done. - * @private - */ -Shuffle.prototype._whenAnimationsDone = function( callback ) { - $.when.apply( null, this._animations ).always( $.proxy( function() { - this._animations.length = 0; - callback.call( this ); - }, this )); -}; - - -/** - * Public Methods - */ - -/** - * The magic. This is what makes the plugin 'shuffle' - * @param {string|Function} [category] Category to filter by. Can be a function - * @param {Object} [sortObj] A sort object which can sort the filtered set - */ -Shuffle.prototype.shuffle = function( category, sortObj ) { - if ( !this.enabled || this.isTransitioning ) { - return; - } - - if ( !category ) { - category = ALL_ITEMS; - } - - this._filter( category ); - - // How many filtered elements? - this._updateItemCount(); - - // Shrink each concealed item - this._shrink(); - - // Update transforms on .filtered elements so they will animate to their new positions - this.sort( sortObj ); -}; - - -/** - * Gets the .filtered elements, sorts them, and passes them to layout. - * @param {Object} opts the options object for the sorted plugin - */ -Shuffle.prototype.sort = function( opts ) { - if ( this.enabled && !this.isTransitioning ) { - this._resetCols(); - - var sortOptions = opts || this.lastSort; - var items = this._getFilteredItems().sorted( sortOptions ); - - this._layout( items ); - - this.lastSort = sortOptions; - } -}; - - -/** - * Reposition everything. - * @param {boolean} isOnlyLayout If true, column and gutter widths won't be - * recalculated. - */ -Shuffle.prototype.update = function( isOnlyLayout ) { - if ( this.enabled && !this.isTransitioning ) { - - if ( !isOnlyLayout ) { - // Get updated colCount - this._setColumns(); - } - - // Layout items - this.sort(); - } -}; - - -/** - * Use this instead of `update()` if you don't need the columns and gutters updated - * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations - * could be off. - */ -Shuffle.prototype.layout = function() { - this.update( true ); -}; - - -/** - * New items have been appended to shuffle. Fade them in sequentially - * @param {jQuery} $newItems jQuery collection of new items - * @param {boolean} [addToEnd=false] If true, new items will be added to the end / bottom - * of the items. If not true, items will be mixed in with the current sort order. - * @param {boolean} [isSequential=true] If false, new items won't sequentially fade in - */ -Shuffle.prototype.appended = function( $newItems, addToEnd, isSequential ) { - this._addItems( $newItems, addToEnd === true, isSequential !== false ); -}; - - -/** - * Disables shuffle from updating dimensions and layout on resize - */ -Shuffle.prototype.disable = function() { - this.enabled = false; -}; - - -/** - * Enables shuffle again - * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters - */ -Shuffle.prototype.enable = function( isUpdateLayout ) { - this.enabled = true; - if ( isUpdateLayout !== false ) { - this.update(); - } -}; - - -/** - * Remove 1 or more shuffle items - * @param {jQuery} $collection A jQuery object containing one or more element in shuffle - * @return {Shuffle} The shuffle object - */ -Shuffle.prototype.remove = function( $collection ) { - - // If this isn't a jquery object, exit - if ( !$collection.length || !$collection.jquery ) { - return; - } - - function handleRemoved() { - // Remove the collection in the callback - $collection.remove(); - - // Update things now that elements have been removed. - this.$items = this._getItems(); - this._updateItemCount(); - - this._fire( Shuffle.EventType.REMOVED, [ $collection, this ] ); - - // Let it get garbage collected - $collection = null; - } - - // Hide collection first. - this._toggleFilterClasses( $(), $collection ); - this._shrink( $collection ); - - this.sort(); - - this.$el.one( Shuffle.EventType.LAYOUT + '.' + SHUFFLE, $.proxy( handleRemoved, this ) ); -}; - - -/** - * Destroys shuffle, removes events, styles, and classes - */ -Shuffle.prototype.destroy = function() { - // If there is more than one shuffle instance on the page, - // removing the resize handler from the window would remove them - // all. This is why a unique value is needed. - $window.off('.' + this.unique); - - // Reset container styles - this.$el - .removeClass( SHUFFLE ) - .removeAttr('style') - .removeData( SHUFFLE ); - - // Reset individual item styles - this.$items - .removeAttr('style') - .removeData('point') - .removeData('scale') - .removeClass([ - Shuffle.ClassName.CONCEALED, - Shuffle.ClassName.FILTERED, - Shuffle.ClassName.SHUFFLE_ITEM - ].join(' ')); - - // Null DOM references - this.$items = null; - this.$el = null; - this.sizer = null; - this.element = null; - - // Set a flag so if a debounced resize has been triggered, - // it can first check if it is actually destroyed and not doing anything - this.destroyed = true; -}; - - -// Plugin definition -$.fn.shuffle = function( opts ) { - var args = Array.prototype.slice.call( arguments, 1 ); - return this.each(function() { - var $this = $( this ); - var shuffle = $this.data( SHUFFLE ); - - // If we don't have a stored shuffle, make a new one and save it - if ( !shuffle ) { - shuffle = new Shuffle( this, opts ); - $this.data( SHUFFLE, shuffle ); - } else if ( typeof opts === 'string' && shuffle[ opts ] ) { - shuffle[ opts ].apply( shuffle, args ); - } - }); -}; - - -// http://stackoverflow.com/a/962890/373422 -function randomize( array ) { - var tmp, current; - var top = array.length; - - if ( !top ) { - return array; - } - - while ( --top ) { - current = Math.floor( Math.random() * (top + 1) ); - tmp = array[ current ]; - array[ current ] = array[ top ]; - array[ top ] = tmp; - } - - return array; -} - - -// You can return `undefined` from the `by` function to revert to DOM order -// This plugin does NOT return a jQuery object. It returns a plain array because -// jQuery sorts everything in DOM order. -$.fn.sorted = function(options) { - var opts = $.extend({}, $.fn.sorted.defaults, options); - var arr = this.get(); - var revert = false; - - if ( !arr.length ) { - return []; - } - - if ( opts.randomize ) { - return randomize( arr ); - } - - // Sort the elements by the opts.by function. - // If we don't have opts.by, default to DOM order - if ( $.isFunction( opts.by ) ) { - arr.sort(function(a, b) { - - // Exit early if we already know we want to revert - if ( revert ) { - return 0; - } - - var valA = opts.by($(a)); - var valB = opts.by($(b)); - - // If both values are undefined, use the DOM order - if ( valA === undefined && valB === undefined ) { - revert = true; - return 0; - } - - if ( valA < valB || valA === 'sortFirst' || valB === 'sortLast' ) { - return -1; - } - - if ( valA > valB || valA === 'sortLast' || valB === 'sortFirst' ) { - return 1; - } - - return 0; - }); - } - - // Revert to the original array if necessary - if ( revert ) { - return this.get(); - } - - if ( opts.reverse ) { - arr.reverse(); - } - - return arr; -}; - - -$.fn.sorted.defaults = { - reverse: false, // Use array.reverse() to reverse the results - by: null, // Sorting function - randomize: false // If true, this will skip the sorting and return a randomized order in the array -}; - -return Shuffle; - -}); \ No newline at end of file diff --git a/docs/js/toc.js b/docs/js/toc.js deleted file mode 100644 index b5244bb..0000000 --- a/docs/js/toc.js +++ /dev/null @@ -1,90 +0,0 @@ -// https://github.com/ghiculescu/jekyll-table-of-contents -// this library modified by fastai to: -// - update the location.href with the correct anchor when a toc item is clicked on -(function($){ - $.fn.toc = function(options) { - var defaults = { - noBackToTopLinks: false, - title: '', - minimumHeaders: 3, - headers: 'h1, h2, h3, h4', - listType: 'ol', // values: [ol|ul] - showEffect: 'show', // values: [show|slideDown|fadeIn|none] - showSpeed: 'slow' // set to 0 to deactivate effect - }, - settings = $.extend(defaults, options); - - var headers = $(settings.headers).filter(function() { - // get all headers with an ID - var previousSiblingName = $(this).prev().attr( "name" ); - if (!this.id && previousSiblingName) { - this.id = $(this).attr( "id", previousSiblingName.replace(/\./g, "-") ); - } - return this.id; - }), output = $(this); - if (!headers.length || headers.length < settings.minimumHeaders || !output.length) { - return; - } - - if (0 === settings.showSpeed) { - settings.showEffect = 'none'; - } - - var render = { - show: function() { output.hide().html(html).show(settings.showSpeed); }, - slideDown: function() { output.hide().html(html).slideDown(settings.showSpeed); }, - fadeIn: function() { output.hide().html(html).fadeIn(settings.showSpeed); }, - none: function() { output.html(html); } - }; - - var get_level = function(ele) { return parseInt(ele.nodeName.replace("H", ""), 10); } - var highest_level = headers.map(function(_, ele) { return get_level(ele); }).get().sort()[0]; - //var return_to_top = ''; - // other nice icons that can be used instead: glyphicon-upload glyphicon-hand-up glyphicon-chevron-up glyphicon-menu-up glyphicon-triangle-top - var level = get_level(headers[0]), - this_level, - html = settings.title + " <"+settings.listType+">"; - headers.on('click', function() { - if (!settings.noBackToTopLinks) { - var pos = $(window).scrollTop(); - window.location.hash = this.id; - $(window).scrollTop(pos); - } - }) - .addClass('clickable-header') - .each(function(_, header) { - base_url = window.location.href; - base_url = base_url.replace(/#.*$/, ""); - this_level = get_level(header); - //if (!settings.noBackToTopLinks && this_level > 1) { - // $(header).addClass('top-level-header').before(return_to_top); - //} - txt = header.textContent.split('¶')[0].split(/\[(test|source)\]/)[0]; - if (!txt) {return;} - if (this_level === level) // same level as before; same indenting - html += "
  • " + txt + ""; - else if (this_level <= level){ // higher level than before; end parent ol - for(i = this_level; i < level; i++) { - html += "
  • " - } - html += "
  • " + txt + ""; - } - else if (this_level > level) { // lower level than before; expand the previous to contain a ol - for(i = this_level; i > level; i--) { - html += "<"+settings.listType+">"+((i-level == 2) ? "
  • " : "
  • ") - } - html += "" + txt + ""; - } - level = this_level; // update for the next one - }); - html += ""; - if (!settings.noBackToTopLinks) { - $(document).on('click', '.back-to-top', function() { - $(window).scrollTop(0); - window.location.hash = ''; - }); - } - - render[settings.showEffect](); - }; -})(jQuery); diff --git a/docs/licenses/LICENSE b/docs/licenses/LICENSE deleted file mode 100644 index 21e88dc..0000000 --- a/docs/licenses/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -/* This license pertains to the docs template, except for the Navgoco jQuery component. */ - -The MIT License (MIT) - -Original theme: Copyright (c) 2016 Tom Johnson -Modifications: Copyright (c) 2017 onwards fast.ai, Inc - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/docs/licenses/LICENSE-BSD-NAVGOCO.txt b/docs/licenses/LICENSE-BSD-NAVGOCO.txt deleted file mode 100644 index 7fdefc3..0000000 --- a/docs/licenses/LICENSE-BSD-NAVGOCO.txt +++ /dev/null @@ -1,27 +0,0 @@ -/* This license pertains to the Navgoco jQuery component used for the sidebar. */ - -Copyright (c) 2013, Christodoulos Tsoulloftas, http://www.komposta.net -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the nor the names of its - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/docs/log.png b/docs/log.png deleted file mode 100644 index c3453e7..0000000 Binary files a/docs/log.png and /dev/null differ diff --git a/docs/logo.jpg b/docs/logo.jpg deleted file mode 100644 index 0ef9845..0000000 Binary files a/docs/logo.jpg and /dev/null differ diff --git a/docs/loop.html b/docs/loop.html deleted file mode 100644 index dced757..0000000 --- a/docs/loop.html +++ /dev/null @@ -1,1642 +0,0 @@ ---- - -title: Controllable loop process - -keywords: fastai -sidebar: home_sidebar - -summary: "iteration with callbacks" ---- - - -
    - {% raw %} - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    from time import sleep
    -
    - -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    class Stuff[source]

    Stuff(name)

    -
    - -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    words = Stuff("model")
    -words["G"] = "generative_model"
    -words["D"] = "discriminative_model"
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    def to_device(single_model,device):
    -    print(f"{single_model} put to device:{device}")
    -    # single_model.to(device)
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    words(to_device)(2)
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    generative_model put to device:2
    -discriminative_model put to device:2
    -
    -
    -
    - -
    - - - -
    -
    {'G': None, 'D': None}
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    words("upper")()
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    {'G': 'GENERATIVE_MODEL', 'D': 'DISCRIMINATIVE_MODEL'}
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    words("__len__")()
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    {'G': 16, 'D': 20}
    -
    - -
    - -
    -
    - -
    -
    -
    -

    Both of the following syntax works

    - -
    -
    -
    -
    -
    - -
    -
    -
    words.G
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    'generative_model'
    -
    - -
    - -
    -
    - -
    -
    -
    -

    In real cases we can do

    -
    model("to")("cuda:1")
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    words(to_device)("cuda:1")
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    generative_model put to device:cuda:1
    -discriminative_model put to device:cuda:1
    -
    -
    -
    - -
    - - - -
    -
    {'G': None, 'D': None}
    -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    method4all[source]

    method4all(f)

    -
    -

    Use this function as a decorator, -The decorated function under Loop class can be used on outer layer

    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    class StorageCore[source]

    StorageCore(start_layer)

    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    class Loop[source]

    Loop(iterable=[], name=None) :: list

    -
    -

    Basic loop class

    - -
    - -
    - -
    -
    - -
    -
    -
    -

    Loop-in-loop concept

    Loop and its inheriting descendants runs on iterable, incuding other [`Loop`](/forgebox/loop#Loop)

    - -
    -
    -
    -
    -
    - -
    -
    -
    l = Loop(range(5,10),name = "hahahha")
    -l
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    layer🍰hahahha
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    class Printer(Loop):
    -    def __call__(self):
    -        print(f"i_{self.core.i}",end="\t")
    -        print(self.core.element)
    -        
    -    def start_call(self):
    -        print(f"start of epoch {self.epoch}")
    -        
    -    def end_call(self):
    -        print(f"end of epoch {self.epoch}")
    -l2 = Printer(l)
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    l2.run()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    start of epoch 0
    -i_0	5
    -i_1	6
    -i_2	7
    -i_3	8
    -i_4	9
    -end of epoch 0
    -
    -
    -
    - -
    -
    - -
    -
    -
    -

    Progress bar

    -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    class ProgressBar[source]

    ProgressBar(iterable=[], jupyter=True, mininterval=1.0, leave=False) :: Loop

    -
    -

    Basic loop class

    - -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    from tqdm.notebook import tqdm,tqdm_notebook
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    pb = ProgressBar(Loop(range(5,10)),jupyter = True,leave=True)
    -pb.run()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    -

    Downstream wraper

    A unique way to contain downstream task in a function, hence a good Error Handling mechanism

    -
    - -
    -
    -
    -
    -
    -

    In cases you don't want error stop the iteration, meanwhile taking down all the error message.

    - -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    error_tolerate[source]

    error_tolerate(downstream_func)

    -
    -

    downstream_func:Downstream function

    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    class Tolerate[source]

    Tolerate(iterable=[]) :: Loop

    -
    -

    Tolerate any error happened downstream -layer2 = Tolerate(upstream_iterable)

    -

    build downstream tasks

    layer3 = OtherApplication(layer2) -layer3.run()

    -

    show the happened error message

    layer3.error_list()

    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    class LambdaCall[source]

    LambdaCall(iterable=[], func='<lambda>', start_func='<lambda>', end_func='<lambda>') :: Loop

    -
    -

    Basic loop class

    - -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    l1 = ProgressBar(Loop(range(1,10)))
    -error_loop = LambdaCall(l1,func= lambda x:(5-x.element)**(-2))
    -
    - -
    -
    -
    - -
    -
    -
    -

    Running this will yield error

    - -
    -
    -
    -
    -
    -
    error_loop.run()
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    def error_on_purpose(x):
    -    if x.element>5:
    -        raise ValueError(f"value too small, {x.element}")
    -
    -l1 = ProgressBar(Loop(range(1,10)))
    -# add the tolerate layer in between
    -l2 = Tolerate(l1)
    -# tolerate can only tolerate the erorr on downstream
    -tolerated_loop = LambdaCall(l2,func=error_on_purpose,end_func=error_on_purpose)
    -l2.run()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    WARNING:5 errors
    -
    -
    -
    - -
    -
    - -
    -
    -
    -

    you can use error_list function to print all the happened error

    - -
    -
    -
    -
    -
    - -
    -
    -
    import pandas as pd
    -pd.DataFrame(l2.error_list())
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    stageiepocherror
    0start_cb-10'StorageCore' object has no attribute 'element'
    1iter_cb50value too small, 6
    2iter_cb60value too small, 7
    3iter_cb70value too small, 8
    4iter_cb80value too small, 9
    5end_cb80value too small, 9
    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    l2.summary()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    Loop layer Tolerate summary:
    -==================================================
    -🍰layer0.0	layer🍰Loop
    ---------------------------------------------------
    -🍰layer1.0	layer🍰ProgressBar
    -	[🐍func_name]	pgbar_data
    -	[⛰doc]	
    -        update progress bar with python dictionary
    -        data: python dictionary
    -        
    -	[😝var]	self,data
    -	[😜names]	t,set_postfix
    -	...................................
    -	[🐍func_name]	pgbar_description
    -	[⛰doc]	
    -        update progress bar prefix with text string
    -        
    -	[😝var]	self,text
    -	[😜names]	t,set_description_str
    -	...................................
    ---------------------------------------------------
    -🍰layer2.0	layer🍰Tolerate
    -	[🐍func_name]	error_list
    -	[⛰doc]	
    -        A list of errors happend so far
    -        
    -	[😝var]	self
    -	[😜names]	errors
    -	...................................
    ---------------------------------------------------
    -🍰layer3.0	layer🍰Lambda<0x119422e30>
    ---------------------------------------------------
    -==================================================
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    -

    You can search for the function documentation

    - -
    -
    -
    -
    -
    - -
    -
    -
    l2.search()
    -
    - -
    -
    -
    - -
    -
    -
    -

    Application upon progress bar

    The function pgbar_data is decorated under [`method4all`](/forgebox/loop#method4all), hence the function can be used else where

    - -
    -
    -
    -
    -
    - -
    -
    -
    from datetime import datetime
    -class Application(Loop):
    -    def __call__(self):
    -        # create some data
    -        loop_data = dict(epoch=self.epoch,i = self.i,
    -                         val = self.element,)
    -        # update data to progress bar
    -        self.pgbar_data(loop_data)
    -        self.pgbar_description(str(datetime.now().strftime("%H:%M:%S")))
    -
    -l3 = Application(ProgressBar(Loop(range(5,10)),jupyter=True,leave=True))
    -l3.run()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    l3.summary()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    Loop layer Application summary:
    -==================================================
    -🍰layer0.0	layer🍰Loop
    ---------------------------------------------------
    -🍰layer1.0	layer🍰ProgressBar
    -	[🐍func_name]	pgbar_data
    -	[⛰doc]	
    -        update progress bar with python dictionary
    -        data: python dictionary
    -        
    -	[😝var]	self,data
    -	[😜names]	t,set_postfix
    -	...................................
    -	[🐍func_name]	pgbar_description
    -	[⛰doc]	
    -        update progress bar prefix with text string
    -        
    -	[😝var]	self,text
    -	[😜names]	t,set_description_str
    -	...................................
    ---------------------------------------------------
    -🍰layer2.0	layer🍰Application
    ---------------------------------------------------
    -==================================================
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    l3.run()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    -

    Event

    Event allows add-hoc callbacks to be created

    - -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    class Event[source]

    Event(iterable=[]) :: Loop

    -
    -

    An event is the landmark with in 1 iteration

    - -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    class ToString(Loop):
    -    def __call__(self,):
    -        self.core.element = f"variable_{self.i}"
    -
    -class ChangeString(Event):
    -    def __init__(self,iterable=[]):
    -        super().__init__(iterable=iterable)
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    def get_frame(li):
    -    layer1 = ProgressBar(Loop(li,"base"),leave=True)
    -    layer2 = ToString(layer1,)
    -    layer3 = ChangeString(layer2)
    -    # you can use this "on" syntax
    -    @layer3.ChangeString.on
    -    def trim(self):
    -        self.core.element = f"Var_{self.element}"
    -        
    -    # or this syntax
    -    @layer3.on_ChangeString
    -    def update(self):
    -        self.pgbar_description(self.element)
    -        
    -    @layer3.before_1st_ChangeString
    -    def print_start(self):
    -        """
    -        decorated
    -        """
    -        print(f"start_{self.epoch}_{self.i}")
    -        print(self.name)
    -    return layer3
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    l = get_frame(range(10))
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    l.core
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    {0.0: layer🍰base, 1.0: layer🍰ProgressBar, 2.0: layer🍰ToString, 3.0: event🌏ChangeString}
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    l.cbs
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    [layer🍰ON_ChangeString_1_trim,
    - layer🍰ON_ChangeString_2_update,
    - layer🍰BEFORE_1ST_ChangeString_3_print_start]
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    l.summary()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    Loop layer ChangeString summary:
    -==================================================
    -🍰layer0.0	layer🍰base
    ---------------------------------------------------
    -🍰layer1.0	layer🍰ProgressBar
    -	[🐍func_name]	pgbar_data
    -	[⛰doc]	
    -        update progress bar with python dictionary
    -        data: python dictionary
    -        
    -	[😝var]	self,data
    -	[😜names]	t,set_postfix
    -	...................................
    -	[🐍func_name]	pgbar_description
    -	[⛰doc]	
    -        update progress bar prefix with text string
    -        
    -	[😝var]	self,text
    -	[😜names]	t,set_description_str
    -	...................................
    ---------------------------------------------------
    -🍰layer2.0	layer🍰ToString
    ---------------------------------------------------
    -🍰layer3.0	event🌏ChangeString
    -	[🐍func_name]	after_last_ChangeString
    -	[⛰doc]	
    -            Append new after_last callback for event:ChangeString
    -            Use this function as decorator
    -        
    -	[😝var]	cls,f
    -	[😜names]	getattr
    -	...................................
    -	[🐍func_name]	before_1st_ChangeString
    -	[⛰doc]	
    -            Append new before_1st callback for event:ChangeString
    -            Use this function as decorator
    -        
    -	[😝var]	cls,f
    -	[😜names]	getattr
    -	...................................
    -	[🐍func_name]	every_end_ChangeString
    -	[⛰doc]	
    -            Append new every_end callback for event:ChangeString
    -            Use this function as decorator
    -        
    -	[😝var]	cls,f
    -	[😜names]	getattr
    -	...................................
    -	[🐍func_name]	every_start_ChangeString
    -	[⛰doc]	
    -            Append new every_start callback for event:ChangeString
    -            Use this function as decorator
    -        
    -	[😝var]	cls,f
    -	[😜names]	getattr
    -	...................................
    -	[🐍func_name]	on_ChangeString
    -	[⛰doc]	
    -            Append new on callback for event:ChangeString
    -            Use this function as decorator
    -        
    -	[😝var]	cls,f
    -	[😜names]	getattr
    -	...................................
    ---------------------------------------------------
    -==================================================
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    l.layers
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    [layer🍰base, layer🍰ProgressBar, layer🍰ToString, event🌏ChangeString]
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    l.run()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    layer = l.layers[0]
    -print(layer)
    -while layer.next_layer!=None:
    -    layer=layer.next_layer
    -    print(layer.start_call.__doc__)
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    layer🍰base
    -None
    -None
    -None
    -
    -
    -
    - -
    -
    - -
    -
    -
    -

    Parallel

    -
    -
    -
    -
    - -
    -
    -
    - -
    -
    -
    from math import sqrt
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    def heavy_calc(x):
    -    sleep(1)
    -    return sqrt(x)
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    %%time
    -list(map(heavy_calc,range(10)))
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    CPU times: user 933 µs, sys: 1.41 ms, total: 2.35 ms
    -Wall time: 10 s
    -
    -
    -
    - -
    - - - -
    -
    [0.0,
    - 1.0,
    - 1.4142135623730951,
    - 1.7320508075688772,
    - 2.0,
    - 2.23606797749979,
    - 2.449489742783178,
    - 2.6457513110645907,
    - 2.8284271247461903,
    - 3.0]
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    %%time
    -Parallel(n_jobs=5,)(delayed(heavy_calc)(i) for i in range(10))
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    CPU times: user 26.5 ms, sys: 21.8 ms, total: 48.3 ms
    -Wall time: 2.79 s
    -
    -
    -
    - -
    - - - -
    -
    [0.0,
    - 1.0,
    - 1.4142135623730951,
    - 1.7320508075688772,
    - 2.0,
    - 2.23606797749979,
    - 2.449489742783178,
    - 2.6457513110645907,
    - 2.8284271247461903,
    - 3.0]
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    def showstuff(*args):
    -    print(args)
    -    for i in args[0]:
    -        print(i)
    -showstuff(a for a in range(5))
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    (<generator object <genexpr> at 0x11b3761d0>,)
    -0
    -1
    -2
    -3
    -4
    -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    class MultiProc:
    -    def __init__(self,loop,n_jobs = 6):
    -        self.loop = loop
    -        self.n_jobs = n_jobs
    -        self.parallel = Parallel(n_jobs=n_jobs)
    -        
    -    def __enter__(self):
    -        loop = self.loop
    -        def one_epoch_parallel(loop):
    -            first = loop.layers[0]
    -            loop.refresh_i()
    -            first.start_callon()
    -            print(1)
    -            self.parallel(delayed(first.__call__)() for element in first)
    -            print(2)
    -            first.end_callon()
    -        self.old = loop.one_epoch
    -        setattr(loop,"one_epoch",MethodType(one_epoch_parallel,loop))
    -        return
    -    
    -    def __exit__(self,exc_type,exc_val,exc_tb):
    -        setattr(self.loop,"one_epoch",self.old)
    -        return 
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    class Calc(Loop):
    -    def __init__(self,iterable):
    -        super().__init__(iterable=iterable)
    -        
    -    def __call__(self):
    -        sleep(1)
    -        self.pgbar_data(dict(sqrt=sqrt(self.element)))
    -        
    -    def end_call(self):
    -        print("done")
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    basic_loop = ProgressBar(Loop(range(10)))
    -test_li = Calc(basic_loop)
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    %%time
    -test_li.run()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    done
    -CPU times: user 55.5 ms, sys: 8.47 ms, total: 64 ms
    -Wall time: 10.1 s
    -
    -
    -
    - -
    -
    - -
    -
    -
    -

    Chunkify for batch cutting

    -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    chunkify[source]

    chunkify(*iterables, bs=32)

    -
    - -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    chunkify(list(range(10)),list(range(10,20)),bs=3)
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    [([0, 1, 2], [10, 11, 12]),
    - ([3, 4, 5], [13, 14, 15]),
    - ([6, 7, 8], [16, 17, 18]),
    - ([9], [19])]
    -
    - -
    - -
    -
    - -
    - {% endraw %} -
    - - diff --git a/docs/loopstack.html b/docs/loopstack.html deleted file mode 100644 index 2012412..0000000 --- a/docs/loopstack.html +++ /dev/null @@ -1,1519 +0,0 @@ ---- - -title: 15 LoopStack - - -keywords: fastai -sidebar: home_sidebar - -summary: "Stack loops in layers" -description: "Stack loops in layers" -nb_path: "nbs/15_loopstack.ipynb" ---- - - -
    - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    To run through iterations quickly, we use the california housing data

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    from sklearn.datasets.california_housing import fetch_california_housing
    -x,y = fetch_california_housing(return_X_y = True)
    -
    -x.shape, y.shape
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    ((20640, 8), (20640,))
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    Normalized Data

    - -
    -
    -
    -
    -
    -

    Preview x input

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    def norm(m,s): return lambda x: (x-m)/s
    -def denorm(m,s): return lambda x: (x*s)+m
    -
    -x_normed = norm(x.mean(0),x.std(0))(x)
    -y_normed = norm(y.mean(),y.std())(y)
    -
    -x_normed = np.clip(x_normed,-2,2)
    -y_normed = np.clip(y_normed,-2,2)
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    x_normed.mean(0).astype(np.float16),x_normed.std(0),\
    -y_normed.mean().astype(np.float16),y_normed.std()
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    (array([-0.04333 ,  0.000478, -0.0397  , -0.04486 , -0.0554  , -0.01229 ,
    -        -0.007812,  0.001071], dtype=float16),
    - array([0.85610596, 0.99901853, 0.53787672, 0.32598025, 0.73420682,
    -        0.09438235, 0.98221114, 0.99421595]),
    - -0.0302,
    - 0.928904447452199)
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    from matplotlib import pyplot as plt
    -%matplotlib inline
    -plt.imshow(x_normed[np.random.choice(range(1000),10)])
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    <matplotlib.image.AxesImage at 0x1a16a7fa50>
    -
    - -
    - -
    - - - -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    x_normed
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    array([[ 2.        ,  0.98214266,  0.62855945, ..., -0.04959654,
    -         1.05254828, -1.32783522],
    -       [ 2.        , -0.60701891,  0.32704136, ..., -0.09251223,
    -         1.04318455, -1.32284391],
    -       [ 1.7826994 ,  1.85618152,  1.15562047, ..., -0.02584253,
    -         1.03850269, -1.33282653],
    -       ...,
    -       [-1.14259331, -0.92485123, -0.09031802, ..., -0.0717345 ,
    -         1.77823747, -0.8237132 ],
    -       [-1.05458292, -0.84539315, -0.04021111, ..., -0.09122515,
    -         1.77823747, -0.87362627],
    -       [-0.78012947, -1.00430931, -0.07044252, ..., -0.04368215,
    -         1.75014627, -0.83369581]])
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    create_event[source]

    create_event(event_name)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    events[source]

    events(*enames)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class LoopStack[source]

    LoopStack(iterable=[], name=None) :: Loop

    -
    -

    Basic loop class

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    TRAIN_EVENTS = ["DATA_PROCESS","FORWARD","LOSS_CALC",
    -                "BACKWARD","OPT_STEP","METRICS"]
    -EVAL_EVENTS = ["DATA_PROCESS","EVAL_WRAP","FORWARD","LOSS_CALC","METRICS"]
    -
    - -
    -
    -
    - -
    - {% endraw %} - -
    -
    -

    Tabulated Metrics

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class MetricTab[source]

    MetricTab()

    -
    -

    An object handling metric running

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    metab = MetricTab()
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    for i in range(100):
    -    sleep(.01)
    -    metab+=dict(loss= np.random.rand()*(100-i))
    -    metab.update(i=i,epoch=i//5,bs = 32,ts = datetime.now())
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    batch_df,batch_mean = metab.mark()
    -display(batch_df)
    -batch_mean
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    iepochbstsloss
    000322020-06-29 23:44:44.96674016.961023
    110322020-06-29 23:44:44.97932013.221317
    220322020-06-29 23:44:44.99155820.029550
    330322020-06-29 23:44:45.00412135.804462
    440322020-06-29 23:44:45.01450279.937055
    ..................
    959519322020-06-29 23:44:46.0932001.311746
    969619322020-06-29 23:44:46.1032833.787564
    979719322020-06-29 23:44:46.1133602.087981
    989819322020-06-29 23:44:46.1251220.246656
    999919322020-06-29 23:44:46.1378250.154635
    -

    100 rows × 5 columns

    -
    -
    - -
    - -
    - - - -
    -
    {'loss': 24.615831910057956,
    - 'epoch': 1,
    - 'span': Timedelta('0 days 00:00:01.171085')}
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    metab.summary()
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - -
    lossepochspan
    024.615832100:00:01.171085
    -
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    train_callbacks[source]

    train_callbacks(loop:Loop)

    -
    -

    call backs allow optimizing model weights

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    eval_callbacks[source]

    eval_callbacks(loop:Loop)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    to_tensor[source]

    to_tensor(x)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    simple_forward[source]

    simple_forward(metric_func:list=[])

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    single_device[source]

    single_device(device)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class TrainLoop[source]

    TrainLoop(data_iter, model=[], opt=[], loss_func=[], loss=[], hp=[], cuda=[], callbacks=[<function train_callbacks at 0x1203e94d0>], tolerate=True) :: LoopStack

    -
    -

    Basic loop class

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class EvalLoop[source]

    EvalLoop(data_iter, callbacks, tolerate=False) :: LoopStack

    -
    -

    Basic loop class

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    from sklearn.model_selection import train_test_split
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    x_train,x_val,y_train, y_val = train_test_split(x_normed,y_normed,test_size = .1)
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    list(a.shape for a in [x_train,x_val,y_train, y_val])
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    [(18576, 8), (2064, 8), (18576,), (2064,)]
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    from torch import nn
    -import torch
    -
    -data_train = list(zip(chunkify(x_train),chunkify(y_train)))
    -data_val = list(zip(chunkify(x_val),chunkify(y_val)))
    -
    -forward_cb = simple_forward([nn.MSELoss()])
    -
    -train_loop = TrainLoop(data_train,tolerate=False,callbacks=[train_callbacks,forward_cb,])
    -val_loop = EvalLoop(data_val,callbacks=[eval_callbacks,forward_cb,])
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    assigning callback <function train_callbacks at 0x1a32fc70e0>
    -assigning callback <function simple_forward.<locals>.simple_forward_cb at 0x1a2e995950>
    -assigning callback <function eval_callbacks at 0x1a32fc7290>
    -assigning callback <function simple_forward.<locals>.simple_forward_cb at 0x1a2e995950>
    -
    -
    -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    @train_loop.every_end_METRICS
    -def run_eval(self):
    -    val_loop.run(1)
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
     
    -
    - -
    -
    -
    - -
    - {% endraw %} - -
    -
    -

    Assigning stuff

    -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    train_loop.model.baseline = nn.Linear(8,1)
    -train_loop.loss_func.mse = torch.nn.MSELoss()
    -train_loop.metric_func.mae = torch.nn.L1Loss() # MAE is L1 loss 
    -train_loop.opt.adam = torch.optim.Adam(train_loop.model.baseline.parameters())
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    find_stuff[source]

    find_stuff(core:StorageCore)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    share_stuff[source]

    share_stuff(loop_from:Loop, loop_to:Loop)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    share_stuff(train_loop,val_loop)
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    train_loop.search()
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    for i in range(10): train_loop.run()
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    maemseepochspan
    00.5438400.470426100:00:00.192830
    10.4694420.370095200:00:00.218338
    20.4359340.328378300:00:00.341273
    30.4210580.309691400:00:00.226564
    40.4139190.301794500:00:00.370209
    50.4107330.298556600:00:00.243021
    60.4094060.297206700:00:00.590279
    70.4088200.296614800:00:00.211286
    80.4085520.296338900:00:00.222686
    90.4084070.2962031000:00:00.243863
    -
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    from matplotlib import pyplot as plt
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    plt.figure(figsize = (12,5))
    -metric_df = train_loop.metric_tab.summary()
    -val_metric_df = val_loop.metric_tab.summary()
    -
    -display(metric_df)
    -display(val_metric_df)
    -plt.plot(metric_df.mse,"bo--",label="train mse")
    -plt.plot(metric_df.mae,"bo",label="train mae")
    -plt.plot(val_metric_df.mse,"ro--",val_metric_df.mae,"ro")
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    maemseepochspan
    00.6382080.643468100:00:03.698205
    10.5029920.419795200:00:03.794402
    20.4521210.352748300:00:02.817318
    30.4280870.322776400:00:03.210466
    40.4172100.309802500:00:03.277518
    50.4127800.304515600:00:02.883348
    60.4109440.302396700:00:03.805901
    70.4101530.301516800:00:03.043291
    80.4097860.301119900:00:02.914900
    90.4095950.3009211000:00:02.387062
    -
    -
    - -
    - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    maemseepochspan
    00.5438400.470426100:00:00.192830
    10.4694420.370095200:00:00.218338
    20.4359340.328378300:00:00.341273
    30.4210580.309691400:00:00.226564
    40.4139190.301794500:00:00.370209
    50.4107330.298556600:00:00.243021
    60.4094060.297206700:00:00.590279
    70.4088200.296614800:00:00.211286
    80.4085520.296338900:00:00.222686
    90.4084070.2962031000:00:00.243863
    -
    -
    - -
    - -
    - - - -
    -
    [<matplotlib.lines.Line2D at 0x1a2f731050>,
    - <matplotlib.lines.Line2D at 0x1a2f461cd0>]
    -
    - -
    - -
    - - - -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    - - diff --git a/docs/minimum.html b/docs/minimum.html deleted file mode 100644 index b777ee2..0000000 --- a/docs/minimum.html +++ /dev/null @@ -1,466 +0,0 @@ ---- - -title: Minimum - - -keywords: fastai -sidebar: home_sidebar - -summary: "Minimal way of managing a **(Directed Acyclic Graph)DAG pipeline**" -description: "Minimal way of managing a **(Directed Acyclic Graph)DAG pipeline**" -nb_path: "nbs/21_minimum.ipynb" ---- - - -
    - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    now[source]

    now()

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    Link(func)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    Link.verbose = 2
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    @Link
    -def abc(a = 2,b=3):
    -    return a**2
    -
    -@Link
    -def process_abc(f = abc,d=2): 
    -    return f*d
    -
    -@Link
    -def step2(d=5,e = process_abc,):
    -    return {"power":e**d,"mod":e%d}
    -
    -@Link
    -def step3(mod):
    -    return mod/2
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    step3()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    [step3] final args []
    -[step3] final kwargs {}
    -
    -
    -
    - -
    - -
    -
    ----------------------------------------------------------------------------
    -TypeError                                 Traceback (most recent call last)
    -<ipython-input-160-93e7421bb413> in <module>
    -----> 1 step3()
    -
    -<ipython-input-155-5099601ed5c0> in __call__(self, *args, **kwargs)
    -    120 
    -    121     def __call__(self,*args,**kwargs,):
    ---> 122         return self.unit_call()(*args,**kwargs)
    -    123 
    -    124     def register_args(self)->None:
    -
    -<ipython-input-155-5099601ed5c0> in called(*args, **kwargs)
    -    109                 print(f"[{self.func_name}] final args {args0}")
    -    110                 print(f"[{self.func_name}] final kwargs {kwargs0}")
    ---> 111             rt = self.func(*args0,**kwargs0)
    -    112 
    -    113             # save outputs
    -
    -TypeError: step3() missing 1 required positional argument: 'mod'
    -
    -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    abc(5)
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    25
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    abc.inputs
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    {'9ddc067c-20ae-4489-88cb-facaf968b2c2': {'abc': {'args': (5,),
    -   'kwargs': {'b': 3, 'a': 2}}}}
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    abc.data
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    {'9ddc067c-20ae-4489-88cb-facaf968b2c2': {'b': 3, 'a': 2, 'abc': 25}}
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    abc.funcs_
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    {'abc': <function __main__.abc(a=2, b=3)>}
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    from inspect import getargspec,getfullargspec
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    def a():return 123
    -def b(a,b=1):return 123
    -def c(*args,a=1,b=2):return a
    -def d(a=1,b:{"type":int}=2,**kwargs, ):return a
    -def e(a=1,**kwargs):return a
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    for f in [a,b,c,d,e]:
    -    print(getfullargspec(f))
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    FullArgSpec(args=[], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={})
    -FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=(1,), kwonlyargs=[], kwonlydefaults=None, annotations={})
    -FullArgSpec(args=[], varargs='args', varkw=None, defaults=None, kwonlyargs=['a', 'b'], kwonlydefaults={'a': 1, 'b': 2}, annotations={})
    -FullArgSpec(args=['a', 'b'], varargs=None, varkw='kwargs', defaults=(1, 2), kwonlyargs=[], kwonlydefaults=None, annotations={'b': {'type': <class 'int'>}})
    -FullArgSpec(args=['a'], varargs=None, varkw='kwargs', defaults=(1,), kwonlyargs=[], kwonlydefaults=None, annotations={})
    -
    -
    -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    arg_spec = getfullargspec(b)
    -
    -kwargs_default = dict()
    -if arg_spec.defaults != None:
    -    kwargs_default.update(dict(zip(arg_spec.args[::-1],arg_spec.defaults[::-1])))
    -if arg_spec.kwonlydefaults != None:
    -    kwargs_default.update(dict(zip(arg_spec.kwonlyargs[::-1],arg_spec.kwonlydefaults[::-1])))
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    kwargs_default
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    {'b': 1}
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    - - diff --git a/docs/multiprocess.html b/docs/multiprocess.html deleted file mode 100644 index d163ad2..0000000 --- a/docs/multiprocess.html +++ /dev/null @@ -1,269 +0,0 @@ ---- - -title: Multiprocessing Helper - - -keywords: fastai -sidebar: home_sidebar - -summary: "Things to smooth up the multiprocessing" -description: "Things to smooth up the multiprocessing" -nb_path: "nbs/09_multiprocess.ipynb" ---- - - -
    - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Separate Process Magic

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class VipaClass[source]

    VipaClass()

    -
    -

    From meditation word Vipassana -Where creating a magic function -you can run a cell without holding the entire notebook

    -
    %%vipas
    -...do things
    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Read single file line by line

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class SingleFileLiner[source]

    SingleFileLiner(file_path:Path, total:int=None)

    -
    -

    Text data reading line by line for multiprocessing

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    sfl = SingleFileLiner("../README.md")
    -from joblib import Parallel, delayed
    -from time import sleep
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    def get_line(x):
    -#     sleep(1)
    -    return x
    -
    -res = Parallel(backend="multiprocessing", n_jobs=6)(delayed(get_line)(i) for i in sfl)
    -
    - -
    -
    -
    - -
    - {% endraw %} - -
    -
    -

    Read dataframe row by row

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class DataFrameRowling[source]

    DataFrameRowling(df)

    -
    -

    Read dataframe row by row

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    import pandas as pd
    -df = pd.DataFrame({"col1":list(range(100))})
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    res = Parallel(backend="multiprocessing", n_jobs=6)(delayed(get_line)(i) for i in DataFrameRowling(df))
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    res[5]
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    col1    5
    -Name: 5, dtype: int64
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    - - diff --git a/docs/optimizers.html b/docs/optimizers.html deleted file mode 100644 index 34fd16b..0000000 --- a/docs/optimizers.html +++ /dev/null @@ -1,378 +0,0 @@ ---- - -title: Optimizer Mangement - -keywords: fastai -sidebar: home_sidebar - -summary: "Handling PyTorch Cuda" ---- - - -
    - {% raw %} - -
    - -
    -
    -
    -

    This handler is created to handle the multiple optimizer situations

    - -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    class Opts[source]

    Opts(*args, **kwargs)

    -
    - -
    - -
    - -
    -
    - -
    -
    -
    -

    Experiment

    -
    -
    -
    -
    -
    - -
    -
    -
    import torch
    -from torch import nn
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    layer1 = nn.Linear(5,5)
    -layer2 = nn.Linear(5,5)
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    op1 = torch.optim.Adam(layer1.parameters())
    -op2 = torch.optim.Adagrad(layer2.parameters())
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    opts = Opts(op1, op2)
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    opts.optimizer_no1
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    Adam (
    -Parameter Group 0
    -    amsgrad: False
    -    betas: (0.9, 0.999)
    -    eps: 1e-08
    -    lr: 0.001
    -    weight_decay: 0
    -)
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    opts.optimizer_no2
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    Adagrad (
    -Parameter Group 0
    -    eps: 1e-10
    -    initial_accumulator_value: 0
    -    lr: 0.01
    -    lr_decay: 0
    -    weight_decay: 0
    -)
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    opts
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    optimizer_no1
    -	<class 'torch.optim.adam.Adam'>
    -	{'lr': 0.001, 'betas': (0.9, 0.999), 'eps': 1e-08, 'weight_decay': 0, 'amsgrad': False}
    -optimizer_no2
    -	<class 'torch.optim.adagrad.Adagrad'>
    -	{'lr': 0.01, 'lr_decay': 0, 'eps': 1e-10, 'weight_decay': 0, 'initial_accumulator_value': 0}
    -
    - -
    - -
    -
    - -
    -
    -
    -

    Let's create some gradients

    - -
    -
    -
    -
    -
    - -
    -
    -
    x = torch.rand(2,5)
    -y_ = -(layer2(torch.nn.functional.relu(layer1(x))).mean())
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    y_.backward()
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    layer1.weight.grad,layer1.bias.grad,layer2.weight.grad,layer2.bias.grad
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    (tensor([[ 0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00],
    -         [-5.7813e-02, -5.0724e-02, -6.1752e-02, -1.1506e-01, -6.0402e-02],
    -         [-4.5386e-04, -2.3771e-04, -2.1409e-04, -6.2308e-04, -3.3177e-04],
    -         [-1.3012e-01, -1.1416e-01, -1.3899e-01, -2.5898e-01, -1.3595e-01],
    -         [ 0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00]]),
    - tensor([ 0.0000, -0.1238, -0.0007, -0.2787,  0.0000]),
    - tensor([[ 0.0000, -0.1671, -0.0036, -0.1062,  0.0000],
    -         [ 0.0000, -0.1671, -0.0036, -0.1062,  0.0000],
    -         [ 0.0000, -0.1671, -0.0036, -0.1062,  0.0000],
    -         [ 0.0000, -0.1671, -0.0036, -0.1062,  0.0000],
    -         [ 0.0000, -0.1671, -0.0036, -0.1062,  0.0000]]),
    - tensor([-0.2000, -0.2000, -0.2000, -0.2000, -0.2000]))
    -
    - -
    - -
    -
    - -
    -
    -
    -

    Take a step for all optimizers

    -
    -
    -
    -
    -
    - -
    -
    -
    opts.step_all()
    -
    - -
    -
    -
    - -
    -
    -
    -

    Zero gradient on all optimizers

    -
    -
    -
    -
    -
    - -
    -
    -
    opts.zero_all()
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    layer1.weight.grad,layer1.bias.grad,layer2.weight.grad,layer2.bias.grad
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    (tensor([[0., 0., 0., 0., 0.],
    -         [0., 0., 0., 0., 0.],
    -         [0., 0., 0., 0., 0.],
    -         [0., 0., 0., 0., 0.],
    -         [0., 0., 0., 0., 0.]]),
    - tensor([0., 0., 0., 0., 0.]),
    - tensor([[0., 0., 0., 0., 0.],
    -         [0., 0., 0., 0., 0.],
    -         [0., 0., 0., 0., 0.],
    -         [0., 0., 0., 0., 0.],
    -         [0., 0., 0., 0., 0.]]),
    - tensor([0., 0., 0., 0., 0.]))
    -
    - -
    - -
    -
    - -
    - {% endraw %} -
    - - diff --git a/docs/pandas_extra.html b/docs/pandas_extra.html deleted file mode 100644 index 622cb85..0000000 --- a/docs/pandas_extra.html +++ /dev/null @@ -1,709 +0,0 @@ ---- - -title: Pandas Extra functions - - -keywords: fastai -sidebar: home_sidebar - -summary: "Extra pandas functions at import" -description: "Extra pandas functions at import" -nb_path: "nbs/01_pandas_extra.ipynb" ---- - - -
    - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Value counts

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    list_vc[source]

    list_vc(df, colname:str, value:str)

    -
    -

    count the values in a column - that each cell is a list

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    col_list_vc[source]

    col_list_vc(col, value:str)

    -
    -

    count the values in a column - that each cell is a list

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Rename by rule

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    default_rename_rule[source]

    default_rename_rule(x:str)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    rename_by_rule[source]

    rename_by_rule(df, rule:Callable=default_rename_rule)

    -
    -

    rename the columns by a rule function

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Rearrage Columns

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    column_order[source]

    column_order(df, *col_names)

    -
    -

    df = df.column_order("col1", "col2", "col3") -will put col1, col2, and col3 as the 1st 3 column

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Testing

    -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    from sklearn.datasets import california_housing
    -
    -cdata = california_housing.fetch_california_housing()
    -
    -df = pd.DataFrame(cdata["data"], columns=cdata["feature_names"])
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    df["old"] = df.HouseAge>20
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    df.vc("old")
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - -
    old
    True14347
    False6293
    -
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    df.rename_by_rule()
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    medinchouseageaveroomsavebedrmspopulationaveoccuplatitudelongitudeold
    08.325241.06.9841271.023810322.02.55555637.88-122.23True
    18.301421.06.2381370.9718802401.02.10984237.86-122.22True
    27.257452.08.2881361.073446496.02.80226037.85-122.24True
    35.643152.05.8173521.073059558.02.54794537.85-122.25True
    43.846252.06.2818531.081081565.02.18146737.85-122.25True
    ..............................
    206351.560325.05.0454551.133333845.02.56060639.48-121.09True
    206362.556818.06.1140351.315789356.03.12280739.49-121.21False
    206371.700017.05.2055431.1200921007.02.32563539.43-121.22False
    206381.867218.05.3295131.171920741.02.12320939.43-121.32False
    206392.388616.05.2547171.1622641387.02.61698139.37-121.24False
    -

    20640 rows × 9 columns

    -
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    df.column_order("old","AveOccup")
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    oldAveOccupMedIncHouseAgeAveRoomsAveBedrmsPopulationLatitudeLongitude
    0True2.5555568.325241.06.9841271.023810322.037.88-122.23
    1True2.1098428.301421.06.2381370.9718802401.037.86-122.22
    2True2.8022607.257452.08.2881361.073446496.037.85-122.24
    3True2.5479455.643152.05.8173521.073059558.037.85-122.25
    4True2.1814673.846252.06.2818531.081081565.037.85-122.25
    ..............................
    20635True2.5606061.560325.05.0454551.133333845.039.48-121.09
    20636False3.1228072.556818.06.1140351.315789356.039.49-121.21
    20637False2.3256351.700017.05.2055431.1200921007.039.43-121.22
    20638False2.1232091.867218.05.3295131.171920741.039.43-121.32
    20639False2.6169812.388616.05.2547171.1622641387.039.37-121.24
    -

    20640 rows × 9 columns

    -
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    - - diff --git a/docs/pl_training.html b/docs/pl_training.html deleted file mode 100644 index 5b8198c..0000000 --- a/docs/pl_training.html +++ /dev/null @@ -1,307 +0,0 @@ ---- - -title: Pytorch Lighting training - - -keywords: fastai -sidebar: home_sidebar - -summary: "on huggingface transformers" -description: "on huggingface transformers" -nb_path: "nbs/72_pl_training.ipynb" ---- - - -
    - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    # !pip install pytorch-lightning==1.3.8
    -# !pip install tensorflow==2.2.0
    -
    - -
    -
    -
    - -
    - {% endraw %} - -
    -
    -

    Load model and tokenizer

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    ner_model_from[source]

    ner_model_from(name:str, dataset:IOBES)

    -
    -

    name: from_pretrain(name)

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    ner_tokenizer_from[source]

    ner_tokenizer_from(name:str)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Lightning data module

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class NERDataModule[source]

    NERDataModule(*args:Any, **kwargs:Any) :: LightningDataModule

    -
    -

    A DataModule standardizes the training, val, test splits, data preparation and transforms. -The main advantage is consistent data splits, data preparation and transforms across models.

    -

    Example::

    - -
    class MyDataModule(LightningDataModule):
    -    def __init__(self):
    -        super().__init__()
    -    def prepare_data(self):
    -        # download, split, etc...
    -        # only called on 1 GPU/TPU in distributed
    -    def setup(self):
    -        # make assignments here (val/train/test split)
    -        # called on every process in DDP
    -    def train_dataloader(self):
    -        train_split = Dataset(...)
    -        return DataLoader(train_split)
    -    def val_dataloader(self):
    -        val_split = Dataset(...)
    -        return DataLoader(val_split)
    -    def test_dataloader(self):
    -        test_split = Dataset(...)
    -        return DataLoader(test_split)
    -    def teardown(self):
    -        # clean up after fit or test
    -        # called on every process in DDP
    -
    -
    -

    A DataModule implements 6 key methods:

    -
      -
    • prepare_data (things to do on 1 GPU/TPU not on every GPU/TPU in distributed mode).
    • -
    • setup (things to do on every accelerator in distributed mode).
    • -
    • train_dataloader the training dataloader.
    • -
    • val_dataloader the val dataloader(s).
    • -
    • test_dataloader the test dataloader(s).
    • -
    • teardown (things to do on every accelerator in distributed mode when finished)
    • -
    -

    This allows you to share a full dataset without explaining how to download, -split transform and process the data

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class NERModule[source]

    NERModule(model) :: LightningModule

    -
    -

    PyTorch lightning module for training ner model

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Enhance pipeline

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    clean_ner_output[source]

    clean_ner_output(outputs)

    -
    -

    Cleaning output for NER task

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class NERInference[source]

    NERInference(model, tokenizer, name=None)

    -
    -

    NER Inference pipeline -ner = NERInference.from_pretrained('xxxx/xxxx') -ner.predict(['text1','text2'])

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    - - diff --git a/docs/sidebar.json b/docs/sidebar.json deleted file mode 100644 index 13258ab..0000000 --- a/docs/sidebar.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "forgebox": { - "Overview": "/", - "Pandas Extra functions": "pandas_extra.html", - "03 Imports": "imports.html", - "Async": "async.html", - "Tools on pandas dataframe": "df.html", - "HTML operation": "html.html", - "Interactive tools": "inter_widgets.html", - "Flatten": "flatten.html", - "spacy toolkit": "spacy.html", - "FreeMap": "freemap.html", - "Multiprocessing Helper": "multiprocess.html", - "Controllable loop process": "loop.html", - "ETL Helper": "etl.html", - "Get static file": "static_file.html", - "15 LoopStack": "loopstack.html", - "Config": "config.html", - "Minimum": "minimum.html", - "01 A logged editable table": "traceable_edit_in_flask.html", - "Dataframe filter": "df_filter.html", - "Hard drive files": "files.html", - "Wild Tree and loss": "wild_tree_and_loss.html", - "Image Widgets": "image_widgets.html", - "Categorical Transformation for DL": "category.html", - "Cosine ": "cosine_search.html", - "Lightning Callbacks": "thunder_callbacks.html", - "Data parts for hf transformers": "hf_transformer_data.html", - "Pytorch Lighting training": "pl_training.html", - "CUDA GPU Management": "CUDA_GPU_Management.html", - "Bert Visualize": "bert_visualize.html", - "NLP data": "bilstm-based-search-on-netflix-data.html", - "Create multi-task adjustment for cross-entropy": "cross_entropy_weighter.html", - "DataFrame PipeLine": "dataframe_pipeline.html", - "Optimizer Mangement": "optimizers.html", - "Turbo ": "turbo.html" - } -} \ No newline at end of file diff --git a/docs/sitemap.xml b/docs/sitemap.xml deleted file mode 100644 index 38a04d6..0000000 --- a/docs/sitemap.xml +++ /dev/null @@ -1,24 +0,0 @@ ---- -layout: none -search: exclude ---- - - - - {% for post in site.posts %} - {% unless post.search == "exclude" %} - - {{site.url}}{{post.url}} - - {% endunless %} - {% endfor %} - - - {% for page in site.pages %} - {% unless page.search == "exclude" %} - - {{site.url}}{{ page.url}} - - {% endunless %} - {% endfor %} - \ No newline at end of file diff --git a/docs/spacy.html b/docs/spacy.html deleted file mode 100644 index 63db92c..0000000 --- a/docs/spacy.html +++ /dev/null @@ -1,463 +0,0 @@ ---- - -title: spacy toolkit - -keywords: fastai -sidebar: home_sidebar - -summary: "Tools enhancing spacy usage" ---- - - -
    - {% raw %} - -
    - -
    -
    - -
    -
    -
    -

    Normalization and cosine distance calculation, between each word of 2 sentences

    - -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    l2norm[source]

    l2norm(x)

    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    normal[source]

    normal(x)

    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    distance[source]

    distance(a, b)

    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    make_map[source]

    make_map(distance_map, th=0.1)

    -
    -

    create a hot spot map between similar token -return dict, token index with matching token index in the target sentence

    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    make_span[source]

    make_span(tok, tok_id, classes)

    -
    -

    create span for token -tok,spacy token -tok_id, span's html id

    -

    return forgebox.html.DOM

    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    make_div[source]

    make_div(doc, id_list, classes_list)

    -
    -

    create div tag for a sentence -doc:spacy doc -id_list, a list of html id -classes_list, a list of classes assigning to the token span

    -

    return forgebox.html.DOM

    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    doc2div[source]

    doc2div(doc, distance_map, th=0.1, is_src=True)

    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    compare_sentences[source]

    compare_sentences(A, B, nlp, th=0.1)

    -
    -

    Compare between sentences -A: str, a sentence -B: str, another sentence -nlp: loaded spacy: eg. from spacy import load;nlp = load("some_model_name"), -see spacy documentation https://spacy.io/usage/spacy-101/

    -

    th:float, threshold for consine distance, smaller it is, fewer matching tokens will be found, -but assume that means higher quality

    - -
    - -
    - -
    -
    - -
    -
    -
    -

    Visualizing Sentence Compare

    -
    -
    -
    -
    -
    -

    Example

      -
    • Suppose you have 2 sentences, name them A and B
    • -
    - -
    -
    -
    -
    -
    - -
    -
    -
    A = """BACKGROUND: In the COU-AA-302 study (NCT00887198), abiraterone acetate plus prednisone (AAP) 
    -significantly improved outcomes in patients with metastatic castration-resistant prostate cancer (mCRPC) 
    -versus prednisone alone. Baseline clinical parameters predicting that treatment response could help inform 
    -clinical decisions were explored. OBJECTIVE: To identify patients who derive the greatest clinical benefit 
    -from AAP treatment. DESIGN, SETTING, AND PARTICIPANTS: A total of 1088 mCRPC patients treated with either 
    -AAP or prednisone in the first-line setting in COU-AA-302 were included in this post hoc analysis. 
    -INTERVENTION: Abiraterone acetate1000mg daily versus placebo, both plus prednisone 10mg daily. 
    -OUTCOME MEASUREMENTS AND STATISTICAL ANALYSIS: Univariate and multivariable Cox regression 
    -analyses were performed, including clinical and pathological parameters for the primary end points overall 
    -survival (OS) and radiographic progression-free survival (rPFS), and secondary study end points. 
    -Tumor-associated baseline parameters independently impacting OS were applied to stratify patients according 
    -to possible treatment effects. RESULTS AND LIMITATIONS: Baseline prostate-specific antigen (PSA), tumor-related 
    -pain as assessed by the Brief Pain Inventory-Short Form (BPI-SF), and Gleason score (GS) at primary diagnosis
    -were identified as tumor-associated variables that independently impacted OS. AAP significantly improved 
    -outcomes versus prednisone in both group 1 (BPI-SF 0-1 and PSA <80 ng/ml and GS <8; p=0.006; hazard ratio 
    -[HR]: 0.61) and group 2 (BPI-SF 2-3 and/or PSA ≥80 ng/ml and/or GS ≥8; p=0.03; HR: 0.84). 
    -The differences observed for treatment effects between groups 1 and 2 for OS (HR: 0.61 vs 0.84), rPFS 
    -(HR: 0.41 vs 0.59), and time to chemotherapy (HR: 0.64 vs 0.71) were not statistically significant. 
    -CONCLUSIONS: AAP significantly improved outcomes in mCRPC patients compared with prednisone alone regardless 
    -of baseline pain and PSA level, and GS at primary diagnosis with no significant differences between observed 
    -treatment effects in groups 1 and 2. PATIENT SUMMARY: Treatment with abiraterone acetate and prednisone 
    -(compared with treatment with prednisone only) for metastatic castration-resistant prostate cancer 
    -increased survival in all patients in the study regardless of pain, prostate-specific antigen levels 
    -at the start of treatment, and Gleason score at primary diagnosis."""
    -
    -B = """'Treatment with abiraterone acetate and prednisone (compared with treatment with prednisone only) 
    -for metastatic castration-resistant prostate cancer increased survival in all patients in the study regardless 
    -of pain, prostate-specific antigen levels at the start of treatment, and Gleason score at primary diagnosis.'
    -"""
    -
    - -
    -
    -
    - -
    -
    -
    -

    You can run the comparation between A & B

    - -
    -
    -
    -
    -
    - -
    -
    -
    from spacy import load
    -nlp = load("en_core_web_sm")
    -
    -compare_sentences(A,B,nlp)
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -

    Sentence A

    -
    - -
    - -
    - - -
    - -
    - -
    - -
    - - -
    -
    BACKGROUND:IntheCOU-AA-302study(NCT00887198),abirateroneacetateplusprednisone(AAP) -significantlyimprovedoutcomesinpatientswithmetastaticcastration-resistantprostatecancer(mCRPC) -versusprednisonealone.Baselineclinicalparameterspredictingthattreatmentresponsecouldhelpinform -clinicaldecisionswereexplored.OBJECTIVE:Toidentifypatientswhoderivethegreatestclinicalbenefit -fromAAPtreatment.DESIGN,SETTING,ANDPARTICIPANTS:Atotalof1088mCRPCpatientstreatedwitheither -AAPorprednisoneinthefirst-linesettinginCOU-AA-302wereincludedinthisposthocanalysis. -INTERVENTION:Abirateroneacetate1000mgdailyversusplacebo,bothplusprednisone10mgdaily. -OUTCOMEMEASUREMENTSANDSTATISTICALANALYSIS:UnivariateandmultivariableCoxregression -analyseswereperformed,includingclinicalandpathologicalparametersfortheprimaryendpointsoverall -survival(OS)andradiographicprogression-freesurvival(rPFS),andsecondarystudyendpoints. -Tumor-associatedbaselineparametersindependentlyimpactingOSwereappliedtostratifypatientsaccording -topossibletreatmenteffects.RESULTSANDLIMITATIONS:Baselineprostate-specificantigen(PSA),tumor-related -painasassessedbytheBriefPainInventory-ShortForm(BPI-SF),andGleasonscore(GS)atprimarydiagnosis -wereidentifiedastumor-associatedvariablesthatindependentlyimpactedOS.AAPsignificantlyimproved -outcomesversusprednisoneinbothgroup1(BPI-SF0-1andPSA<80ng/mlandGS<8;p=0.006;hazardratio -[HR]:0.61)andgroup2(BPI-SF2-3and/orPSA≥80ng/mland/orGS≥8;p=0.03;HR:0.84). -Thedifferencesobservedfortreatmenteffectsbetweengroups1and2forOS(HR:0.61vs0.84),rPFS -(HR:0.41vs0.59),andtimetochemotherapy(HR:0.64vs0.71)werenotstatisticallysignificant. -CONCLUSIONS:AAPsignificantlyimprovedoutcomesinmCRPCpatientscomparedwithprednisonealoneregardless -ofbaselinepainandPSAlevel,andGSatprimarydiagnosiswithnosignificantdifferencesbetweenobserved -treatmenteffectsingroups1and2.PATIENTSUMMARY:Treatmentwithabirateroneacetateandprednisone -(comparedwithtreatmentwithprednisoneonly)formetastaticcastration-resistantprostatecancer -increasedsurvivalinallpatientsinthestudyregardlessofpain,prostate-specificantigenlevels -atthestartoftreatment,andGleasonscoreatprimarydiagnosis.
    -
    - -
    - -
    - - -
    -

    Sentence B

    -
    - -
    - -
    - - -
    - -
    - -
    - -
    - - -
    -
    'Treatmentwithabirateroneacetateandprednisone(comparedwithtreatmentwithprednisoneonly) -formetastaticcastration-resistantprostatecancerincreasedsurvivalinallpatientsinthestudyregardless -ofpain,prostate-specificantigenlevelsatthestartoftreatment,andGleasonscoreatprimarydiagnosis.' -
    -
    - -
    - -
    - - -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} -
    - - diff --git a/docs/static_file.html b/docs/static_file.html deleted file mode 100644 index 1082a0a..0000000 --- a/docs/static_file.html +++ /dev/null @@ -1,220 +0,0 @@ ---- - -title: Get static file - - -keywords: fastai -sidebar: home_sidebar - -summary: "get none-python file, like js and html" -description: "get none-python file, like js and html" -nb_path: "nbs/12_static_file.ipynb" ---- - - -
    - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    get_static[source]

    get_static()

    -
    -

    return the absolute path of forgebox.static

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    open_static[source]

    open_static(relative_path:str)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    The static file directory

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    get_static()
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    PosixPath('/Users/xiaochen.zhang/github/forgebox/forgebox/static')
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    Open relative path

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    open_static("mlm/visual.html")
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    "<div>\n    <h2>Masked language modeling visualization</h2>\n    <script>\n        {{mlm_visual_js}}\n\n        var data = JSON.parse('{{data}}');\n        var text =  `{{text}}`;\n        var output_id = '{{output_id}}'\n        mlm_visualize(data,text,output_id);\n    </script>\n\n    <div id='{{output_id}}'></div>\n</div>"
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    print(open_static("mlm/visual.js")[:500])
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    var mlm_visualize = (data, text, output_id) => {
    -    var {
    -        Sentence,
    -        ControlBar,
    -        att_obj
    -    } = attention_factory(data, text, output_id)
    -
    -    var sentence = new Sentence();
    -    var control_bar = new ControlBar({
    -        nb_heads: att_obj.attention.length,
    -        current_head: 0
    -    });
    -
    -    control_bar.sensitive.add_callback(
    -        control_bar.func_print_change,
    -        control_bar.change_current_head(att_obj),
    -    )
    -
    -    $(`#${output_id}`).append(control_bar.dom)
    -   
    -
    -
    -
    - -
    -
    - -
    - {% endraw %} - -
    - - diff --git a/docs/test_nbdev.html b/docs/test_nbdev.html deleted file mode 100644 index 485bd26..0000000 --- a/docs/test_nbdev.html +++ /dev/null @@ -1,75 +0,0 @@ ---- - -title: The big title - -keywords: fastai -sidebar: home_sidebar - -summary: "The not big one" ---- - - -
    - {% raw %} - -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    test_nbdev_func[source]

    test_nbdev_func()

    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    - - -
    -

    test_nbdev_func[source]

    test_nbdev_func()

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} -
    - - diff --git a/docs/thunder_callbacks.html b/docs/thunder_callbacks.html deleted file mode 100644 index 2e93103..0000000 --- a/docs/thunder_callbacks.html +++ /dev/null @@ -1,147 +0,0 @@ ---- - -title: Lightning Callbacks - - -keywords: fastai -sidebar: home_sidebar - -summary: "Thunder, the DIYed pytorch-lightening callbacks" -description: "Thunder, the DIYed pytorch-lightening callbacks" -nb_path: "nbs/61_thunder_callbacks.ipynb" ---- - - -
    - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    unfreeze[source]

    unfreeze()

    -
    -

    unfreeze this module, and its sub modules

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    freeze[source]

    freeze()

    -
    -

    freeze this module, and its sub modules

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class DataFrameMetricsCallback[source]

    DataFrameMetricsCallback() :: Callback

    -
    -

    A metrics callback keep showing pandas dataframe

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    UnfreezeScheduler[source]

    UnfreezeScheduler(frozen_epochs:int=2)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    - - diff --git a/docs/tooltips.json b/docs/tooltips.json deleted file mode 100644 index cee21d3..0000000 --- a/docs/tooltips.json +++ /dev/null @@ -1,19 +0,0 @@ ---- -layout: null -search: exclude ---- - -{ -"entries": -[ -{% for page in site.tooltips %} -{ -"doc_id": "{{ page.doc_id }}", -"body": "{{ page.content | strip_newlines | replace: '\', '\\\\' | replace: '"', '\\"' }}" -} {% unless forloop.last %},{% endunless %} -{% endfor %} -] -} - - - diff --git a/docs/traceable_edit_in_flask.html b/docs/traceable_edit_in_flask.html deleted file mode 100644 index a32f857..0000000 --- a/docs/traceable_edit_in_flask.html +++ /dev/null @@ -1,294 +0,0 @@ ---- - -title: 01 A logged editable table - - -keywords: fastai -sidebar: home_sidebar - -summary: "Traceable editable table in flask" -description: "Traceable editable table in flask" -nb_path: "nbs/30_traceable_edit_in_flask.ipynb" ---- - - -
    - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    from flask import Flask
    -app = Flask(__name__)
    -
    -@app.route('/')
    -def hello_world():
    -    return 'Hello, World!'
    -
    - -
    -
    -
    - -
    - {% endraw %} - -
    -
    -

    Run a simple applitcation

    -
    -
    -
    - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    get_static[source]

    get_static()

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    edit_js[source]

    edit_js()

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class DefaultTemp[source]

    DefaultTemp(source, block_start_string='{%', block_end_string='%}', variable_start_string='{{', variable_end_string='}}', comment_start_string='{#', comment_end_string='#}', line_statement_prefix=None, line_comment_prefix=None, trim_blocks=False, lstrip_blocks=False, newline_sequence='\n', keep_trailing_newline=False, extensions=(), optimized=True, undefined=Undefined, finalize=None, autoescape=False, enable_async=False) :: Template

    -
    -

    Jinjia template with some default render config

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Create sample data

    -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    con = ce("sqlite:///sample.db")
    -
    -sample_df = pd.DataFrame(dict(name=["Darrow","Virginia","Sevro",]*20,
    -                              house =["Andromedus","Augustus","Barca"]*20,
    -                              age=[20,18,17]*20))
    -
    -sample_df.to_sql("sample_table",index_label="id",
    -                 index=True,
    -                 con = con, method='multi',
    -                 if_exists="replace")
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class Editable[source]

    Editable(name, app, table_name, con, id_col, log_con, log_table='editable_log', columns=None)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Testing editable frontend

    -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    app = Flask(__name__)
    -
    -# Create Editable pages around sample_table
    -Editable("table1", # route/task name
    -         app, # flask app to wrap around
    -         table_name="sample_table", # target table name
    -         id_col="id", # unique column
    -         con = con,
    -         log_con=con
    -        )
    -
    -app.run(host="0.0.0.0",port = 4242,debug=False)
    -
    - -
    -
    -
    - -
    - {% endraw %} - -
    -
    -

    Retrieve the log

    -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    from forgebox.df import PandasDisplay
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    with PandasDisplay(max_colwidth = 0,max_rows=100):
    -    display(pd.read_sql('editable_log',con = con))
    -
    - -
    -
    -
    - -
    - {% endraw %} - -
    - - diff --git a/docs/train.html b/docs/train.html deleted file mode 100644 index a0003d4..0000000 --- a/docs/train.html +++ /dev/null @@ -1,1024 +0,0 @@ ---- - -title: Title - -keywords: fastai -sidebar: home_sidebar - -summary: "summary" ---- - - -
    - {% raw %} - -
    - -
    -
    -
    -

    PyTorch Train

    -
    -
    -
    -
    - -
    -
    -
    - -
    -
    -
    import torch
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    def create_event(event_name):
    -    class ProductEvent(Event):pass
    -    
    -    ProductEvent.__name__=event_name
    -    return ProductEvent
    -
    -def events(*event_names):
    -    return tuple(list(map(create_event,event_names)))
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    events("e1","e2")[0]()
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    layer:>>>e1
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    class 
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    l1.summary()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    Loop layer e1 summary:
    -==================================================
    -🍰layer0.0	layer:>>>e1
    -	[🐍func_name]	after_last_e1
    -	[⛰doc]	
    -            Append new after_last callback for event:e1
    -            Use this function as decorator
    -        
    -	[😝var]	cls,f
    -	[😜names]	getattr
    -	...................................
    -	[🐍func_name]	before_1st_e1
    -	[⛰doc]	
    -            Append new before_1st callback for event:e1
    -            Use this function as decorator
    -        
    -	[😝var]	cls,f
    -	[😜names]	getattr
    -	...................................
    -	[🐍func_name]	on_e1
    -	[⛰doc]	
    -            Append new on callback for event:e1
    -            Use this function as decorator
    -        
    -	[😝var]	cls,f
    -	[😜names]	getattr
    -	...................................
    ---------------------------------------------------
    -==================================================
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    class DataLoop(Loop):
    -    def __init__(self,dataloader=None):
    -        super().__init__(iterable=dataloader)
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    from types import MethodType
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    class LoopStack:
    -    @classmethod
    -    def from_Loops(cls,*Loops):
    -        cls.Loops = dict()
    -        for L in Loops:
    -            setattr(cls,L.__name__,L)
    -            cls.Loops.update({L.__name__:L})
    -        def init(self,iterable=[]):
    -            last = iterable
    -            for k,L in self.Loops.items():
    -                layer = L(last) 
    -                last = layer
    -            self.layer = last
    -        
    -        setattr(cls,"__init__",MethodType(init,cls))
    -        return cls
    -    
    -    def __getattr__(self,k):
    -        return getattr(self.layer,k)
    -    
    -    def __repr__(self):
    -        return f"LoopStack with\n\t"+"\n\t".join(self.Loops.keys())
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    STANDARD_TRAIN_PROCESS = events("PREPROCESS","FORWARD","CALC_LOSS","BACKWARD","OPTIMIZING","METRICS")
    -STANDARD_EVAL_PROCESS = events("PREPROCESS","EVAL_SCOPE","FORWARD","CALC_LOSS","METRICS")
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    TrainLoop = LoopStack.from_Loops(DataLoop,
    -                                 ProgressBar,
    -                                 Tolerate,
    -                                 *STANDARD_TRAIN_PROCESS)
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    train_loop = TrainLoop(range(100))
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    train_loop
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    LoopStack with
    -	DataLoop
    -	ProgressBar
    -	Tolerate
    -	PREPROCESS
    -	FORWARD
    -	CALC_LOSS
    -	BACKWARD
    -	OPTIMIZING
    -	METRICS
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    train_loop.run()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    train_loop.summary()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    Loop layer opt_step summary:
    -==================================================
    -🍰layer0.0	layer:>>>DataLoop
    ---------------------------------------------------
    -🍰layer1.0	layer:>>>Progressb Bar
    -	[🐍func_name]	pgbar_data
    -	[⛰doc]	
    -        update progress bar with python dictionary
    -        data: python dictionary
    -        
    -	[😝var]	self,data
    -	[😜names]	t,set_postfix
    -	...................................
    -	[🐍func_name]	pgbar_description
    -	[⛰doc]	
    -        update progress bar prefix with text string
    -        
    -	[😝var]	self,text
    -	[😜names]	t,set_description_str
    -	...................................
    ---------------------------------------------------
    -🍰layer2.0	layer:>>>Tolerate
    -	[🐍func_name]	error_list
    -	[⛰doc]	
    -        A list of errors happend so far
    -        
    -	[😝var]	self
    -	[😜names]	errors
    -	...................................
    ---------------------------------------------------
    -🍰layer3.0	layer:>>>before_forward
    -	[🐍func_name]	on_before_forward
    -	[⛰doc]	
    -            Excute callback for event:before_forward
    -        
    -	[😝var]	self
    -	[😜names]	__call__
    -	...................................
    -	[🐍func_name]	set_before_forward
    -	[⛰doc]	
    -            Append new callback for event:before_forward
    -            Use this function as decorator
    -        
    -	[😝var]	self,f
    -	[😜names]	on
    -	...................................
    ---------------------------------------------------
    -🍰layer4.0	layer:>>>forward
    -	[🐍func_name]	on_forward
    -	[⛰doc]	
    -            Excute callback for event:forward
    -        
    -	[😝var]	self
    -	[😜names]	__call__
    -	...................................
    -	[🐍func_name]	set_forward
    -	[⛰doc]	
    -            Append new callback for event:forward
    -            Use this function as decorator
    -        
    -	[😝var]	self,f
    -	[😜names]	on
    -	...................................
    ---------------------------------------------------
    -🍰layer5.0	layer:>>>calc_loss
    -	[🐍func_name]	on_calc_loss
    -	[⛰doc]	
    -            Excute callback for event:calc_loss
    -        
    -	[😝var]	self
    -	[😜names]	__call__
    -	...................................
    -	[🐍func_name]	set_calc_loss
    -	[⛰doc]	
    -            Append new callback for event:calc_loss
    -            Use this function as decorator
    -        
    -	[😝var]	self,f
    -	[😜names]	on
    -	...................................
    ---------------------------------------------------
    -🍰layer6.0	layer:>>>backward
    -	[🐍func_name]	on_backward
    -	[⛰doc]	
    -            Excute callback for event:backward
    -        
    -	[😝var]	self
    -	[😜names]	__call__
    -	...................................
    -	[🐍func_name]	set_backward
    -	[⛰doc]	
    -            Append new callback for event:backward
    -            Use this function as decorator
    -        
    -	[😝var]	self,f
    -	[😜names]	on
    -	...................................
    ---------------------------------------------------
    -🍰layer7.0	layer:>>>opt_step
    -	[🐍func_name]	on_opt_step
    -	[⛰doc]	
    -            Excute callback for event:opt_step
    -        
    -	[😝var]	self
    -	[😜names]	__call__
    -	...................................
    -	[🐍func_name]	set_opt_step
    -	[⛰doc]	
    -            Append new callback for event:opt_step
    -            Use this function as decorator
    -        
    -	[😝var]	self,f
    -	[😜names]	on
    -	...................................
    ---------------------------------------------------
    -==================================================
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    @train_loop.layer.set_opt_step
    -def opt_step(self):
    -    print("step")
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    train_loop.run()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -step
    -
    -
    -
    -
    - -
    -
    - -
    - {% endraw %} -
    - - diff --git a/docs/turbo.html b/docs/turbo.html deleted file mode 100644 index 790d2d1..0000000 --- a/docs/turbo.html +++ /dev/null @@ -1,851 +0,0 @@ ---- - -title: Turbo - -keywords: fastai -sidebar: home_sidebar - -summary: "Iteration manager" ---- - - -
    - {% raw %} - -
    - -
    -
    -
    - -
    -
    -
    import pandas as pd
    -import numpy as np
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    import math
    -class turboBase(object):
    -    def __init__(self,length, batch_size=16,shuffle = True):
    -        self.length = length
    -        self.shuffle = shuffle 
    -        self.batch_size = batch_size
    -        self.march_funcs = {}
    -        self.march_order = []
    -        self.shuffle_data()
    -        self.idx = 0
    -        
    -    def epoch(self):
    -        gen = iter(self)
    -        t= tqdm(range(len(self)))
    -        for i in t:
    -            rt = next(gen)
    -            if rt["success"]==False:
    -                break
    -                
    -    def __repr__(self):
    -        return f"<turbo bs:{self.batch_size} len:{len(self)}>"
    -        
    -    def shuffle_data(self):
    -        if self.shuffle:
    -            self.order = np.random.permutation(len(self))
    -        
    -    def __len__(self):
    -        return math.ceil(float(self.length)/float(self.batch_size))
    -    
    -    def __iter__(self):
    -        raise NotImplemented("Please define the __iter__ function first")
    -    
    -    def march(self,f):
    -        funame = f.__name__
    -        self.march_funcs[funame] = f
    -        if funame not in self.march_order:
    -            self.march_order.append(funame)
    -        def wraper(*args,**kwargs):
    -            return f(*args,**kwargs)
    -        return wraper
    -    
    -    def __call__(self,x):
    -        for m in self.march_order:
    -            x = self.march_funcs[m](x)
    -        return x
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    df = pd.read_csv("data/netflix_titles.csv")
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    df
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    show_idtypetitledirectorcastcountrydate_addedrelease_yearratingdurationlisted_indescription
    081145628MovieNorm of the North: King Sized AdventureRichard Finn, Tim MaltbyAlan Marriott, Andrew Toth, Brian Dobson, Cole...United States, India, South Korea, ChinaSeptember 9, 20192019TV-PG90 minChildren & Family Movies, ComediesBefore planning an awesome wedding for his gra...
    180117401MovieJandino: Whatever it TakesNaNJandino AsporaatUnited KingdomSeptember 9, 20162016TV-MA94 minStand-Up ComedyJandino Asporaat riffs on the challenges of ra...
    270234439TV ShowTransformers PrimeNaNPeter Cullen, Sumalee Montano, Frank Welker, J...United StatesSeptember 8, 20182013TV-Y7-FV1 SeasonKids' TVWith the help of three human allies, the Autob...
    380058654TV ShowTransformers: Robots in DisguiseNaNWill Friedle, Darren Criss, Constance Zimmer, ...United StatesSeptember 8, 20182016TV-Y71 SeasonKids' TVWhen a prison ship crash unleashes hundreds of...
    480125979Movie#realityhighFernando LebrijaNesta Cooper, Kate Walsh, John Michael Higgins...United StatesSeptember 8, 20172017TV-1499 minComediesWhen nerdy high schooler Dani finally attracts...
    .......................................
    622980000063TV ShowRed vs. BlueNaNBurnie Burns, Jason Saldaña, Gustavo Sorola, G...United StatesNaN2015NR13 SeasonsTV Action & Adventure, TV Comedies, TV Sci-Fi ...This parody of first-person shooter games, mil...
    623070286564TV ShowMaronNaNMarc Maron, Judd Hirsch, Josh Brener, Nora Zeh...United StatesNaN2016TV-MA4 SeasonsTV ComediesMarc Maron stars as Marc Maron, who interviews...
    623180116008MovieLittle Baby Bum: Nursery Rhyme FriendsNaNNaNNaNNaN2016NaN60 minMoviesNursery rhymes and original music for children...
    623270281022TV ShowA Young Doctor's Notebook and Other StoriesNaNDaniel Radcliffe, Jon Hamm, Adam Godley, Chris...United KingdomNaN2013TV-MA2 SeasonsBritish TV Shows, TV Comedies, TV DramasSet during the Russian Revolution, this comic ...
    623370153404TV ShowFriendsNaNJennifer Aniston, Courteney Cox, Lisa Kudrow, ...United StatesNaN2003TV-1410 SeasonsClassic & Cult TV, TV ComediesThis hit sitcom follows the merry misadventure...
    -

    6234 rows × 12 columns

    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    from tqdm import tqdm
    -class dfTurbo(turboBase):
    -    def __init__(self,df, batch_size=16, shuffle=False):
    -        super().__init__(len(df),batch_size=batch_size,shuffle=shuffle)
    -        self.df = df
    -        
    -    def __iter__(self):
    -        self.idx = 0
    -        return self
    -        
    -    def __next__(self):
    -        if self.shuffle:
    -            a = self.order[self.idx]
    -        else:
    -            a = self.idx
    -        b=a+1
    -        try:
    -            self.idx+=1
    -            dt = self(self.df[self.batch_size*a:self.batch_size*b])
    -            return  {"data":dt,"success":True}
    -        except Exception as e:
    -            self.idx=0
    -            return {"data":{"msg":str(e)}, "success":False}
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    dft = dfTurbo(df)
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    @dft.march
    -def directors(df):
    -    print(list(df[~df.director.isna()]["director"]))
    -    return df
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    dft.epoch()
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
     51%|█████     | 199/390 [00:00<00:00, 901.99it/s]
    -
    -
    - -
    - -
    -
    ['Richard Finn, Tim Maltby', 'Fernando Lebrija', 'Gabe Ibáñez', 'Rodrigo Toro, Francisco Schultz', 'Henrik Ruben Genz', 'José Miguel Contreras', 'Daniel Alfredson', 'Munjal Shroff, Tilak Shetty', 'Munjal Shroff, Tilak Shetty', 'Tilak Shetty']
    -['Tilak Shetty', 'Munjal Shroff, Tilak Shetty', 'Gaspar Noé', "Tom O'Brien", 'Antoine Bardou-Jacquet', 'Mitch Dickman', 'Brad Anderson', 'Austin Stark', 'Hannah Fidell', 'Madeleine Gavin', 'Sopon Sukdapisit', 'Kevin R. Adams, Joe Ksander', 'Ian Samuels']
    -['Franck Ribière', 'Daniele Thompson', 'Anubhav Sinha', 'Maha Venkatesh', 'Tharun Bhascker', 'Şenol Sönmez', 'Tom Gianas, Ross R. Shuman', 'Rajkumar Hirani', 'Robert Osman, Nathanael Wiseman', 'Jon Spira', 'Mez Tharatorn', 'Adisorn Tresirikasem', 'Mez Tharatorn']
    -['Banjong Pisanthanakun', 'Banjong Pisanthanakun, Paween Purikitpanya, Songyos Sugmakanan, Parkpoom Wongpoom, Visute Poolvoralaks', 'Banjong Pisanthanakun, Parkpoom Wongpoom', 'Chayanop Boonprakob', 'Susan Johnson', 'Lynn Shelton', 'Farhan Alam', 'Chad Archibald', 'Brian Baugh', 'A. L. Vijay', 'Ryan Coogler', 'Ben Palmer', 'Chris Howe']
    -['Ken Kwapis', 'Park In-je', 'Rod Blackhurst, Brian McGinn', 'Jesse V. Johnson', 'Mahsun Kırmızıgül', 'Monique Gardenberg', 'Mike Flanagan', 'Jacob LaMendola']
    -['Ritesh Batra', 'Dylan Howitt', 'William Lau', 'Mana Yasuda', 'Brian De Palma', 'Mana Yasuda', 'Rizal Mantovani', 'Han Yan', 'Jeremy Saulnier', 'Kim A. Snyder', 'Raditya Dika', 'Rocky Soraya']
    -['Sunil Soraya', 'Álvaro Longoria, Gerardo Olivares', 'Brendan Byrne', 'Gupse Özay', 'Jim Mickle', 'Jumpei Mizusaki, Koji Morimoto, Michael Arias, Masaru Matsumoto, Arthell Isom, Henry Thurlow, Takanobu Mizuno, Elsa Nakamichi, Hajime Sasaki, Shinji Takagi', 'Chi Fat Chan', 'Nabil Ayouch', 'Rob LaDuca, Robert C. Ramirez', 'Mangesh Hadawale', 'Wong Kar Wai']
    -['Rob Cohen', 'Louis J. Horvitz', 'Linda Saffire, Adam Schlesinger', 'Luis Lopez, Clay Tweel', 'Otilia Portillo Padua', 'Le Van Kiet', 'Eric Summer, Éric Warin', 'B. V. Nandini Reddy', 'B. V. Nandini Reddy', 'Mario Van Peebles', 'Ava DuVernay', 'Sonia Lowman', 'Benjamin Turner', 'Michael J. Bassett', 'Troy Miller', 'Tan Bing']
    -['Warren P. Sonoda', 'Álex de la Iglesia', 'Rahul Ravindran', 'Archie Borders', 'Bonni Cohen, Jon Shenk', 'Bobcat Goldthwait', 'Deepti Naval', 'Morgan Neville', 'Anthony Byrne', 'Chris Moukarbel', 'Ana Lily Amirpour', 'Alex Winter', 'Kemi Adetiba', 'Toka McBaror']
    -['Gilles Paquet-Brenner', 'Niyi Akinmolayan', 'Rashida Jones, Alan Hicks', 'Scott Aukerman', 'Mariano Barroso', 'Amara Cash']
    -['Kiko Cruz Claverol, Patricia Font', 'Bedran Güzel', 'Chun Wong', 'Coerte Voorhees, John Voorhees', 'Samuel D. Pollard', 'Ham Tran', 'Feng Xiaogang', 'Gary Michael Schultz']
    -['Liv Ullmann', 'Sandeep Reddy Vanga', 'Jacques Perrin, Jacques Cluzaud', 'Justin Benson, Aaron Moorhead', 'Michael Bonfiglio', 'Zack Whedon', 'Eric Stoltz']
    -['Conrad Helten', 'Morgan Neville', 'Teo Konuralp', 'Jesse V. Johnson', 'Chris Perkel', 'Cheh Chang', 'Manny Rodriguez', 'Robert Eggers', 'Chuck Russell', 'John Erick Dowdle']
    -['Edgar Wright', 'Tony Elliott', 'Troy Miller', 'Louis C.K.', 'Jeremy Coon, Tim Skousen', 'Orlando von Einsiedel', 'Tom Donahue', 'Michèle Ohayon', 'Timothy Woodward Jr.']
    -['Nia Dinata', "Mark O'Connor", 'Ajithkumar', 'Lucky Kuswandi', 'Riri Riza', 'Vijay Milton', 'Susannah Heath-Eves', 'Santwana Bardoloi', 'Atanu Ghosh', 'Amitava Bhattacharya', 'Partha Chakraborty']
    -['Raffi Ahmad, Arie Azis', 'Angelina Jolie', 'Pavel Parkhomenko', 'Azfar Jafri', 'R. Ellis Frazier', 'R. Ellis Frazier', 'Yance Ford', 'Mark Tonderai', 'Roman Atwood, Ben Pluimer', 'Dan Forrer', 'Kip Andersen, Keegan Kuhn', 'B. V. Nandini Reddy', 'Randall Lobb', 'Stacie Passon', 'Manop Janjarasskul']
    -['Shinsuke Sato', 'Chatchai Katenut, Manussa Vorasingha, Tanwarin Sukkhapisit, Poj Arnon', 'Ariel Vromen', 'Nicole Holofcener', 'Jerry G. Angelo', 'Michael Feifer', 'Elle Callahan', 'Alex Stapleton', 'Kıvanç Baruönü']
    -['Teng Huatao', 'Nzingha Stewart', 'Mark Dennis, Ben Foster', 'Ben Wallis', 'Dan Krauss', 'David Soren', 'Alessio Cremonini', 'Elaine McMillion Sheldon']
    -['Michael Simon', 'Joram Lürsen', 'Oliver Frampton', 'Mike Binder', 'Ryan Murphy', 'Orlando von Einsiedel', 'Mark Franchetti, Andrew Meier', 'Damián Romay', 'Trent Haaga', 'Mary Harron', 'Roger Donaldson', 'Petra Costa', 'Steven C. Miller']
    -['Richard Miron', 'Tony Leondis', 'Roger Kumble', 'Kunle Afolayan', 'Craig Gillespie', 'Nick Cassavetes', 'Clint Eastwood', 'Kunle Afolayan', 'Petra Costa, Lea Glob', 'Roger Allers, Jill Culton', 'Kunle Afolayan', 'Wolfgang Petersen', 'Jonathan Demme', 'Bernie Denk']
    -['Ivan Reitman', 'Greg Mottola', 'Kunle Afolayan', 'Kunle Afolayan', 'Alejandro Agresti', 'Daniel Stamm', 'Phillip Noyce', 'Tony Scott', 'Ahmed Zain', 'Mohamed Hamdy', 'Dennis Dugan', 'Peter Ho', 'Jordi Llompart', 'Rian Johnson']
    -['Olivier Marchal', 'Dennis Iliadis', 'Qaushiq Mukherjee', 'Sudip Bandyopadhyay', 'Onir', 'Jatla Siddartha', 'Jeremy Saulnier', 'Kanwal Sethi', 'Banjong Pisanthanakun', 'Alfonso Cuarón', 'Samuel Jouy', 'Akiva Goldsman', 'Damien Leone', 'Karen Moncrieff', 'Jean-Pierre Devillers']
    -['Sophon Sakdaphisit', 'Curtis Hanson', 'Young Jun Lee', 'Rajiv Mehra', 'Toshiyuki Kubooka', 'Toshiyuki Kubooka', 'Todd S. Yellin', 'Jesse Adang, Syrine Boulanouar', 'Rajiv Mehra']
    -['Elizabeth Chai Vasarhelyi', 'Toshiya Shinohara', 'Toshiya Shinohara', 'Toshiya Shinohara', 'Mohammed Hussain', 'Eli Craig', 'Parambrata Chatterjee', 'Shammi Kapoor', 'Umesh Mehra', 'Masahiko Murata', 'Masahiko Murata', 'Masahiko Murata']
    -['Hirotsugu Kawasaki', 'Toshiyuki Tsuru', 'Tensai Okamura', 'Florian Schnell', 'Josh Izenberg, Wynn Padula', 'Thierry Demaizière, Alban Teurlai', 'Spike Lee', 'Latif Faiziyev, Umesh Mehra', 'Gastón Duprat, Mariano Cohn', 'Bette Gordon', 'Gary Wang', 'Raz Degan', 'Israel Adrián Caetano', 'Mariano Cohn, Gastón Duprat', 'Drew Stone']
    -['Joram Lürsen', 'Jelle de Jonge', 'Afia Nathaniel', 'Luke Jurevicius', 'Sean Cisterna', 'Will Allen', 'Nacho G. Velilla']
    -['David Serrano', 'Jay Chapman', 'Jenny Gage', 'Kaila York', 'Ifa Isfansyah', 'Stan Lathan', 'Angga Dwimas Sasongko', 'Evgeny Afineevsky', 'Ryan Polito', 'Kabir Bhatia', 'Russell Crowe', 'Andrew Sandler']
    -['Ava DuVernay', 'Dave Higby', 'Richie Smyth', 'Andibachtiar Yusuf', 'Dustin Nguyen', 'Chris Eigeman', 'Stanley Tong', 'David France', 'Vandana Kataria', 'Angga Dwimas Sasongko', 'Riri Riza']
    -['Olaf de Fleur', 'Tamara Jenkins', 'Onur Bilgetay', 'Vincenzo Natali', 'Tugçe Soysop', 'Jacob Joice, Steve Ball', 'Craig Goodwill', 'Riri Riza', 'Mickey Liddell']
    -['Michael D. Black', 'Juani Libonatti', 'DJ Chen', 'Dani de la Torre', 'Jerrold Tarog', 'Judah Friedlander', 'Errol Morris', 'Oliver Blackburn', 'Park Joon-hwa', 'Saravana Rajendran', 'Onir', 'Jitendra Tiwari, Pranav Singh']
    -['Vivek Wagh', 'Riri Riza', 'Alex Israel', 'Lee Fulkerson', 'Joe Camp', 'Kavi Raz', 'Nick Simon', 'Don Mancini', 'Brandon Jones', 'Alain Desrochers', 'Brian Volk-Weiss', 'Deniz Gamze Ergüven']
    -['Robert Vince', 'Everardo González', 'Matt Kay', 'Drake Doremus', 'Robert Vince', 'Osgood Perkins', 'Werner Herzog', 'Julien Rambaldi', 'Yvan Attal', 'Benjamin Weill', 'Scott Hussion, Seth Fuller', 'Wilson Yip', 'Griffin Dunne']
    -['Roger Gual', 'J. Davis', 'Rob Smat', 'Tinge Krishnan', 'Aleksey German', 'Eric Zaragosa', 'Sergio Barrejón', 'Sandi Tan', 'Vijay Yelakanti', 'Katherine Dieckmann', 'Natalie Portman', 'John Murlowski']
    -['Ozan Açıktan', 'Craig Brewer', 'Billy Lyons', 'Michael Steed', 'Zak Hilditch', 'Michael Steiner', 'Vlad Yudin', 'Paul Berczeller, Mark Radice']
    -['Quentin Tarantino', 'Chris Buck, Jennifer Lee, Patrick Osborne, Lauren MacMullan, John Kahrs, Nathan Greno, Byron Howard, Stevie Wermers, Dean Wellins, Kevin Deters, Roger Allers, Mike Gabriel, Mark Henn', 'Andrew Slater', 'Glen Goei, Gavin Yap', 'S.S. Rajamouli', 'Brian Klein', 'Katy Chevigny, Ross Kauffman', 'Sarik Andreasyan', 'Huw Cordey', 'Yuen Woo-ping', 'Steve Brill']
    -['Don Michael Paul', 'Noah Baumbach', 'Jonathan Mostow', 'Brett Haley', 'Gillian Robespierre', 'Tobe Hooper', 'Daniel Benmayor', 'Abu Bakr Shawky', 'Jedd Wider, Todd Wider', 'Nagesh Kukunoor', 'Priyadarshan', 'Raj Kanwar', 'Pooja Bhatt', 'Satish Kaushik', 'Nikhil Advani']
    -['Anees Bazmee', 'Andrew Bujalski', 'Ben Wheatley', 'Riri Riza', 'Anthony Giordano', 'Wyatt Cenac', 'Joanna Lombardi, Bruno Ascenzo', 'David Batty', 'Zak Hilditch', 'Jennifer Siebel Newsom', 'Heidi Ewing, Rachel Grady', 'Jeremy Rush']
    -['Luis Javier Henaine', 'Anand Kamalakar', 'Don Michael Paul', 'Eric Idle, Aubrey Powell', 'Anthony Giordano', 'Will Yapp']
    -['Eric Idle', 'Will Yapp', 'Terry Hughes, Ian MacNaughton', 'Roger Graef, James Rogan', 'Terry Jones', 'Ian MacNaughton', 'Albert Sharpe', 'Leslye Headland', 'Jay Karas', 'Prakash Satam', 'Barry Sonnenfeld', 'Omoni Oboli']
    -['Thomas Vinterberg', 'Marcos Bucay', 'Peter Lepeniotis', 'Kim Jee-woon', 'Rajesh Touchriver', 'David Lam', 'David Batty', 'David Batty', 'David Batty', 'Timo Tjahjanto']
    -['Reem Kherici', 'Adze Ugah', 'Steve Gukas', 'Ciarán Foy', 'Frank Rajah Arase', 'Yılmaz Erdoğan', 'Tope Oshin', 'Daniel Sánchez Arévalo', 'Don Omope', 'Ed Perkins', 'Steven Soderbergh']
    -['Tope Oshin', 'Udai Singh Pawar', 'Guntur Soeharjanto', 'Thiru', 'Federico Lemos', 'Harald Zwart', 'Bruce McDonald', 'Bobcat Goldthwait', 'Bassam Tariq', 'Leslie Iwerks', 'Kim Joo-hyung', 'Ciarán Foy', 'Louie Psihoyos']
    -['Tom Forrest', 'Milan Luthria', 'John Crowley', 'Ranjit Tiwari', 'Tom Fassaert', 'Adam Dubin', 'Cary Joji Fukunaga', 'Aaron Hann, Mario Miscione', 'Ahmet Katıksız', 'Alexandros Avranas', 'Anindya Chatterjee']
    -['Anik Datta', 'Rajkumar Hirani', 'Ishaan Trivedi', 'Biswajeet Bora', 'Sohail Tatari', 'David Stubbs', 'Madhur Bhandarkar', 'Parveen Kumar', 'Matías Gueilburt', 'Ananth Narayan Mahadevan', 'Ah Loong', 'Girish Malik', 'Debaloy Dey']
    -['Martin Rosete', "Jasmine D'Souza", 'Ben C. Lucas', 'Rohit Jugraj', 'Shakti Samanta', 'Raj B. Shetty', 'Navneet Behal', 'Sukhbir Singh', 'Naresh Saigal', 'Ram Gopal Varma', 'Dhruv Dhawan', 'Thomas Sorriaux', 'Toshiyuki Kubooka', 'Noriyuki Abe', 'Noriyuki Abe']
    -['Clovis Cornillac', 'Hajime Kamegaki', 'Hajime Kamegaki', 'Jean-François Blais', 'Derek Hui', 'Kevin MacDonald', 'Stefano Sollima', 'Dave Higby', 'Leïla Sy, Kery James', 'Shaad Ali']
    -['Mahmoud al Massad', 'Yesim Ustaoglu', 'Jan Suter', 'Lucy Cohen', 'McG', 'Noah Baumbach', 'Christopher Guest', 'Gareth Evans', 'Paul Urkijo Alijo', 'Johanna Demetrakas', 'Padraic McKinley', 'Rizal Mantovani', 'Kief Davidson']
    -['Sara Colangelo', 'Mahmoud Sabbagh', 'Borja Cobeaga', 'Jonathan Demme', 'Leo Riley', 'Hakan Algül', 'Vince Gilligan', 'Brad Anderson', 'Bolanle Austen-Peters', 'Sion Sono', 'Dennis Rovira van Boekholt', 'Angga Dwimas Sasongko', 'Mohamed Diab']
    -['Naoto Amazutsumi', 'Paul Greengrass', 'Rusty Cundieff, Darin Scott', 'Jay Karas', 'Alastair Fothergill', 'James Yukich', 'Maciej Dejczer', 'Rusty Nixon', 'Lee Tamahori', 'Richard Rich', 'Michael Bay', 'Michael Bay', 'Ted Demme']
    -['Bernard Rose', 'McG', 'McG', 'Lee Yoon-jung', 'Paul Haggis', 'Troy Miller', 'Dave Green', 'Wojciech Marczewski', 'Andrzej Bartkowiak', 'Roy Poortmans', 'Brian Robbins', 'Mark Helfrich']
    -['Jon Hurwitz, Hayden Schlossberg', 'Bille Woodruff', 'Janusz Majewski', 'Alex Merkin', 'Janusz Majewski', 'Alex Proyas', 'Vrinda Samartha', 'Jacek Koprowicz', 'Barry Sonnenfeld', 'Nicholaus Goossen', 'Scott Hicks', 'Steven Soderbergh', 'Steven Soderbergh']
    -['Morgan Spurlock', 'Martin Scorsese', 'Stig Bergqvist, Paul Demeyer', 'Wes Craven', 'Asif Kapadia', 'Robert Rodriguez, Frank Miller', 'Dorian Fernández-Moris', 'Jeannot Szwarc', 'Bryan Singer', 'Ash Brannon, Chris Buck', 'Andy Tennant', 'Rob Reiner', 'Marek Piwowski', 'Kunle Afolayan', 'Brian Levant']
    -['Brian Levant', 'Stanisław Różewicz', 'Gabriele Muccino', 'Igor Kovalyov, Norton Virgien', 'Krzysztof Zanussi', 'Noah Baumbach', 'Robert Schwentke', 'Danny Boyle', 'Wolfgang Petersen', 'Paul Feig', 'Alex Smith, Andrew J. Smith', 'Antoni Krauze', 'Stanisław Różewicz']
    -['Simranjit Singh Hundal', 'Justin G. Dyck', 'Ram Gopal Varma', 'N. Linguswamy', 'Deep Joshi', 'Antoine Fuqua', 'John Curran', 'Rakeysh Omprakash Mehra', 'Anurag Kashyap', 'Manjeet Maan', 'Shagufta Rafique', 'Shakun Batra', 'Andrew Renzi', 'Tinu Pappachan']
    -['Amitoj Mann', 'Amarpreet G S Chabbra', 'Paresh Mokashi', 'Anurag Basu', 'Rohit Jugraj', 'Ashutosh Gowariker', 'Atharv Baluja', 'Vishal Bhardwaj', 'Leslie Small, Tim Story', 'Shannon Hartman', 'Rohit Jugraj', 'Shashanka Ghosh', 'Steve Greenwood', 'Puneet Sira', 'Aziz Mirza']
    -["Renzil D'Silva", 'Smeep Kang', 'Sameer Sharma', 'Chandan Arora', 'Baljit Singh Deo', 'Amitoj Mann', 'Jennifer Peedom', 'Mysskin', 'Rajan Madhav', 'Raaghav Dar', 'Ishi Rudell', 'Ishi Rudell', 'David Lee Miller', 'Thiru', 'Amit Saxena']
    -['Pankaj Batra', 'Jaivi Dhanda', 'Suman Ghosh', 'Kabir Khan', 'Akshay Akkineni', 'Nidhi Sharma', 'Mastan Alibhai Burmawalla, Abbas Alibhai Burmawalla', 'Abbas Alibhai Burmawalla, Mastan Alibhai Burmawalla', 'Vipin Parashar', 'Vikram Pradhan', 'Vijay', 'Eduardo Chauvet', 'Sundar C.', 'Sartaj Singh Pannu']
    -['Vikramaditya Motwane', 'James McTeigue', 'N. Linguswamy', 'Ayaan Mukherji', 'Sidharth Malhotra', 'Saket Behl', 'Kevin Smith', 'Anjum Shahzad', 'Geun-hyun Cho', 'Christian Desmares, Franck Ekinci', 'Kyran Kelly', 'Adam Wood', 'Zeke Norton', 'Karen J. Lloyd', 'Andrew Tan, Michael Goguen', 'William Lau']
    -['Ezekiel Norton', 'Conrad Helten', 'Ezekiel Norton', 'Conrad Helten, Ezekiel Norton, Michael Goguen', 'Alê Abreu', 'Carlos Therón', 'Francesco Carrozzini', 'Noah Baumbach', 'Vlad Yudin', 'Karen J. Lloyd', 'Benjamin Turner, Gabe Turner']
    -['Steve Race', 'Brett Harvey', 'Roger Allers, Gaëtan Brizzi, Paul Brizzi, Joan C. Gratz, Mohammed Saeed Harib, Tomm Moore, Nina Paley, Bill Plympton, Joann Sfar, Michael Socha', 'Keiichi Hara', 'William Lau', 'Audu Paden, Eric Radomski', 'Claude Barras', 'Jean-Loup Felicioli, Alain Gagnol', 'Toa Fraser', 'Vibeke Idsøe']
    -['Chan-sang Lim', 'Kyoko Miyake', 'Carlos Algara, Alejandro Martinez-Beltran', 'Stephen Donnelly, Olly Reid, Jun Falkenstein', 'Mikhil Musale', 'Riccardo Pilizzeri', 'Guilherme Fontes', 'Aamir Bashir', 'Alejandro Fernández Almendras']
    -['Álex de la Iglesia', 'Ishi Rudell', 'David Schalko', 'Pieter Kuijpers', 'Prashant Nair', 'Paul Taublieb, Jon Freeman', 'Riccardo Milani', 'Larry Elikann', 'Robert Markowitz', 'Eric Laneuville']
    -['Joel Oliansky', 'Roy Campanella II', 'Arthur Allan Seidelman', 'John Herzfeld', 'Buzz Kulik', 'Richard Michaels', 'Linda Otto', 'Roger Young', 'Vincent Kok', 'Fellipe Barbosa', 'Christian Zübert', 'David Mackenzie']
    -['David Palmer, Dax Shepard', 'Luke Snellin', 'Xavier Durringer', 'Jack C. Newell', 'Cecilia Atán, Valeria Pivato', 'Gus Van Sant', 'Saratswadee Wongsomphet', 'Kirati Nakintanon', 'Antongiulio Panizzi', 'Pawan Kumar']
    -['Patricia Rozema', 'Trey Edward Shults', 'Christian Charles', 'Bronwen Hughes', 'Orlando von Einsiedel', 'Phillip Youmans', 'Zhang Yimou', 'John Ridley', 'Lucas Margutti', 'Neal Brennan', 'Azazel Jacobs', 'Jung Ji-woo', 'Leslie Small']
    -['Tejas Prabha Vijay Deoskar', 'Anees Bazmee', 'Jim Fall', 'Marita Grabiak', 'Jason Priestley', 'Neill Blomkamp', 'Noah Baumbach', "Matt D'Avella", 'Parthiban', 'Morgan Matthews', 'Marcus Raboy', 'Kief Davidson, Richard Ladkani']
    -['Luis Ara, Ignacio Jaunsolo', 'Abhishek Sharma', 'John Schultz', 'Damien O’Connor', 'Joseduardo Giordano, Sergio Goyri Jr.', 'Rudy Soedjarwo', 'Alice Rohrwacher', 'Kabir Bhatia, Titien Wattimena', 'Nandita Das', 'Leena Yadav', 'Romain Gavras', 'Sebastián Hofmann']
    -['Heidi Brandenburg, Mathew Orzel', 'John Luessenhop', 'Mike Disa', 'Pali Yahya', 'Mati Diop', 'Moses Inwang', 'Jérémy Clapin', 'Mandla Dube', 'Mike Ezuruonye', 'Cheta Chukwu', 'Roger Russell', 'Toka McBaror']
    -['Leslie Small', 'Frank Oz', 'Lu Yang', 'Edward Zwick', 'Basava Shankar Eeday', 'Prakash Satam', 'Elle-Máijá Tailfeathers, Kathleen Hepburn', 'Martin Scorsese', 'Dante Lam']
    -['Shreyas Talpade', 'Seth Barrish', 'Steve Ball', 'Sanjiv Jaiswal', 'Marta Jaenes, Rosa Márquez', 'Daniel Raim', 'Denny Lu, Mike Myhre', 'Luis Ara', 'María Jose Cuevas', 'Oz Rodriguez', 'Aleksandr Chernyaev, Fedor Lyass', 'Robert Altman']
    -['Ric Roman Waugh', 'Cary Murnion, Jonathan Milott', 'Jon Alpert', 'Ibai Abad', 'Charles A. Nichols, Iwao Takamoto', 'David Ayer', 'John Irvin', 'Simon Wells', 'David Ayer', 'Julio Soto Gurpide', 'Julien Abraham']
    -['Tsutomu Mizushima', 'Nate Adams, Adam Carolla', 'Clay Kaytis', 'Barbra Streisand, Jim Gable', 'Qaushiq Mukherjee, Nikon', 'Chris Sparling', 'Qaushiq Mukherjee', 'Kathryn Bigelow']
    -['Monika Mitchell', 'Noah Baumbach, Jake Paltrow', 'Fernando Colomo', 'Josh Wakely', 'Troy Miller', 'Jacob Kornbluth', 'Jon Gunn', 'Jan Suter, Raúl Campos Delgado', 'Anne Fontaine', 'Joshua Caldwell', 'Mike Judge', 'Bruce W. Smith', 'Eva Orner']
    -['Craig Brewer', 'Àlex Pastor, David Pastor', 'KVR Mahendra', 'Andrew Jenks', 'Ivan Reitman', 'John Schlesinger', 'Akiva Schaffer', 'Andy Tennant', 'Juan Carlos Rulfo', 'Christian Ditter', 'Raj R', 'Sergio Leone', 'Jim Field Smith', 'Bruce McCulloch', 'Steven Spielberg']
    -['William Brent Bell', 'Hugh WIlson', 'Sam Raimi', 'Neal Brennan', 'Robert Aldrich', 'Marco Schnabel', 'Francis Ford Coppola', 'Lasse Hallström', 'Oliver Stone', 'Jason Reitman', 'Raja Gosnell', 'David Fincher', 'Robert Vince']
    -['Rocky Soraya', 'Raditya Dika', 'David Paul Meyer', 'Savage Steve Holland', 'Savage Steve Holland', 'Troy Nixey', 'Scott McAboy', 'Raymie Muzquiz, Stu Livingston', 'Stephen Herek', 'Joe Menendez', 'Vince Marcello', 'David R. Ellis', 'Eric Bross']
    -['Will Eisenberg', 'Matheus Souza', 'Sara Dosa', 'Bradley Walsh', 'Orson Welles', 'Morgan Neville', 'Benjamin Ross', 'Stephen Hopkins', 'Steve Paley', 'Shannon Hartman, Michelle Caputo', 'Leslie Iwerks', 'Na Hyeon']
    -['Jerry Seinfeld', 'Houda Benyamina', 'Jerry Rothwell, Reuben Atlas', 'Kristin Hanggi', 'Joe Dante', 'Alex Zamm', 'Chris Smith', 'Tilak Shetty', 'Dee Rees', 'Glenn Miller']
    -['Nicolas Winding Refn', 'Timo Vuorensola', 'Robb Dipple', 'Sarah Gavron', 'Eli Roth', 'Daniel Goldhaber', 'Asri Bendacha', 'Fred Cavayé', 'Joel Coen, Ethan Coen', 'Shane Acker']
    -['Wash Westmoreland', 'Alessandro Angulo', 'Mauro Scandolari', 'Arjun Jandyala', 'Shashanka Ghosh, Samit Basu', 'Naoko Yamada', 'Sergio Pablos', 'Anand Tucker', 'Valli Bindana', 'Nate Adams, Adam Carolla']
    -['Makoto Shinkai', 'V C Abhilash', 'Justin G. Dyck', 'Nila Madhab Panda', 'Sameer Vidwans', 'Timo Tjahjanto', 'Nakul Singh Sawhney', 'Nishanth Ravindaran, Jathin Sanker Raj', 'Bill Guttentag, Michael Ware', 'Gajendra Ahire', 'Swapna Waghmare Joshi', 'Raymond McGrath', 'Adele K. Thomas, Richard Bailey']
    -['Richard Bailey', 'Julien Leclercq', 'Aitor Arregi, Jon Garaño', "Remo D'Souza", 'Radhika Rao, Vinay Sapru', 'Volker Weicker', 'Manjeet Singh', 'Oliver Stone', 'Nick Mead', 'Gautier & Leduc', 'Marcus Raboy']
    -['Timothy Woodward Jr.', 'Lance Bangs', 'Matt Piedmont', 'Erik Matti', 'Christopher Guest', 'John Scheinfeld', 'Rhys Thomas', 'Christopher Storer', 'Jeremy Saulnier', 'Jennifer Baichwal, Nicholas de Pencier', 'Tom Ford', 'J.M. Berrios']
    -['Josh Aronson', 'Alain Desrochers', 'Estela Renner', 'Jeff Wadlow', 'Laurent Cantet', 'Shannon Hartman', 'Raúl Campos, Jan Suter', 'Natalia Valdebenito', 'Marcelo Galvão', 'Lorene Machado', 'Richard Donner']
    -['Kevin Reynolds', 'Marina Seresesky', 'Tony Kaye', 'Kenny Leon', 'Peter Segal', 'David Salzberg, Christian Tureaud', 'Daniel Mann', 'Richard Brooks', 'Michael Kampa', 'Harvey Lowry', 'James Dearden', 'Jack Starrett', 'Les Mayfield']
    -['David Lean', 'Tarun Mansukhani', 'Jennifer Westcott', 'Robert Clouse', 'Valeria Golino', 'Stuart Baird', 'Gregory Hoblit', 'Terry Gilliam', 'Drea Cooper, Zackary Canepari', 'Fred M. Wilcox', 'David Silberg', 'Vincente Minnelli, Charles Walters', 'Robert Altman', 'Mathieu Kassovitz', 'Randal Kleiser']
    -['Ernie Barbarash', 'Michael A. Nickles', 'Ken Marino', 'Lionel C. Martin', 'Clint Eastwood', 'Joe Boyd', 'Jeffrey W. Byrd', 'Scott Stewart', 'Alfonso Arau', 'Ellen Weissbrod', 'Michael Anderson', 'Stanley Kubrick', 'Theodore Witcher', 'Callie Khouri, Jesse V. Johnson']
    -['Brett Ratner', 'Gil Kenan', 'Lewis Milestone, Carol Reed', 'Jared Hess', 'Gene Quintano', 'Lewis Milestone', 'Charles Stone III', 'Nicholas Ray', 'Sam Mendes', 'Roman Polanski', 'John Dahl', 'Stanley Tong', 'Blayne Weaver', 'Billy Bob Thornton']
    -["Sam O'Steen", 'Sam Raimi', 'David Fairhead, Anthony Palmer', 'Adam McKay', 'Gordon Parks', 'Neil Jordan', 'John Stephenson', 'Norman Jewison', 'David Fincher', 'John Dahl', 'Manolo Caro', 'David Michôd', 'Tony Scott', 'Marco Bonfanti', 'Lilly Wachowski, Lana Wachowski', 'Lilly Wachowski, Lana Wachowski']
    -['Lilly Wachowski, Lana Wachowski', 'Everardo González', 'Alan J. Pakula', 'Kevin Donovan', 'Charlotte Zwerin', 'Pete Travis', 'Nick Moore', 'Rodrigo Guardiola, Gabriel Cruz Rivas', 'Ruben Fleischer', 'Neeraj Pandey', 'Indrajit Nattoji', 'Raj Kumar Gupta', "Remo D'Souza"]
    -["Remo D'Souza", 'Arnab Chaudhuri', 'Rana Ranbir', 'Anurag Basu', 'David Zucker', 'Momoko Kamiya', 'Momoko Kamiya', 'Harry Baweja', 'Ken Ghosh', 'Justin G. Dyck', 'Priyadarshan, Kookie V. Gulati', 'Vivek Agnihotri', 'Umesh Shukla', 'Habib Faisal', 'Bobby Roth']
    -['Halder Gomes', 'Tony Zierra', 'Amitoj Mann', 'Raj Kumar Gupta', 'B. Unnikrishnan', 'Milan Luthria', 'Madhur Bhandarkar', 'Sajid Khan', 'Saji Surendran', 'Ksshitij Chaudhary', 'Abhishek Kapoor', 'Sundar C.', 'Gary Binkow', 'Nikhil Advani']
    -['Anurag Basu', 'Lance Bangs', 'Chad Hartigan', 'Nishikant Kamat', 'Navinder Pal Singh', 'Raj Kumar Gupta', 'Dibakar Banerjee', 'Tigmanshu Dhulia', 'Kunal Deshmukh', 'Prakash Jha', 'R. Kannan', 'Gaurav Narayanan', 'Kevin Layne', 'Jon J. Whelan', 'Leanne Gater']
    -['Jennifer M. Kroot', 'Jay Russell', 'Wally Pfister', 'Akin Omotoso', 'Shyam Benegal', 'Satyajit Bhatkal', 'Bharat Jain', 'Alo Sarkar', 'Rajeev Chaudhari', 'Vishal Mishra', 'Iñaki Dorronsoro', 'Takuya Inaba', 'Ali Bin Matar, Ibrahim Bin Mohamed', 'Daniel Ablin', 'Buta Singh']
    -['Abbas Alibhai Burmawalla, Mastan Alibhai Burmawalla', 'Jami', 'Ali Samadi Ahadi', 'Anurag Singh', 'Ashok Nanda', 'Navaniat Singh', 'Shweta Basu Prasad', 'Jesse V. Johnson', 'D Ho']
    -['Jitender Pawar', 'Erik Canuel', 'Param Gill', 'Jack Zagha Kababie', 'Ksshitij Chaudhary', 'Richard Mears', 'Heidi Ewing, Rachel Grady', 'Moto Sakakibara', 'Emilio Martínez Lázaro']
    -['Craig Monahan', 'Gillian Armstrong', 'Jon Reiner, Brad Rothschild', 'John Duigan', 'Mu Chu', 'Henry Sarwer-Foner', 'Will Lovelace, Dylan Southern', 'Jim Monaco', 'Sherif Ismail', 'Dava Whisenant', 'Yen Cheng-kuo', 'James Wan', 'Karim El Sobky', 'Mohamed Samy', 'Sameh Abdulaziz', 'Husam El-Gohari']
    -['Liz Plonka', 'Sam Patton', 'Bobcat Goldthwait', 'Rupert Jones', 'Sonia Kennebeck', 'David Pablos']
    -['Maya Gallus', 'Cavi Borges, Luciano Vidigal', 'Dani Levy', "Alma Har'el", 'Alex Parkinson, Richard da Costa', 'Kevin Peeples', 'Frant Gwo', 'Steven Spielberg', 'Jay Karas', 'Harrison Smith', 'Sonny Mallhi']
    -['Robert Vince', 'Jeff Garlin', 'Jan Suter, Raúl Campos', 'Michael Barnett', 'Andrew Nackman', 'Ole Bornedal', 'Andrew Niccol', 'Isabelle Nanty', 'Rob Epstein, Jeffrey Friedman', 'Antonio Morabito', 'Rene Bueno', 'John Woo', 'Nicolás López', 'Patricia Ferreira']
    -['Nahnatchka Khan', 'Sachin Yardi', 'Sachin Yardi', 'Partho Mitra', 'Santram Varma', 'Rakeysh Omprakash Mehra', 'Paul Spurrier', 'Han Han', 'Pawan Kripalani', 'Bhushan Patel', 'Raj Nidimoru, Krishna D.K.', 'Alexandra Dean']
    -['Cosima Spender', 'Simon Curtis', 'Jang Jae-hyun', 'Charlie McDowell', 'Liam Lynch', 'Hao Wu', 'Felipe Cano', 'Gabriela Tagliavini', 'Joe Berlinger', 'Ismail Farouk', 'Lee Jeong-beom', 'William Bindley']
    -['Fernando Ayllón', 'Maya Zinshtein', 'Vishal Bhardwaj', 'Jill Bauer, Ronna Gradus', 'Justin McConnell', 'Lasse Hallström, Joe Johnston', 'Bryce Wagoner', 'Steven Brill', 'Kim Sung-hoon', 'Norberto López Amado', 'Mary Mazzio']
    -['Joe Piscatella', 'Rahul Dholakia', 'David Michôd', 'Mark Craig', 'Ketan Mehta', 'Raúl Campos, Jan Suter', 'Alex Richanbach', 'Marcus Raboy', 'Christopher Smith', 'Nadia Hallgren', 'Sudabeh Mortezai', 'McG', 'Richard Shepard']
    -['Matthew Cooke', 'Mike Diva, Akiva Schaffer', 'Jean-Patrick Benes', 'Christopher Storer', 'Trisha Ziff', 'Vasan Bala', 'Tig Notaro', 'John Bridcut']
    -['Lance Bangs', 'Mike Fleiss', 'Barry Jenkins', 'Linda Mendoza', 'Aanand Rai', 'Sharon Grimberg', 'Akram Farouk', 'Christel Gibson', 'Andrew Stanton', 'Manav Shah', 'Antoine Fuqua', 'Jimmy Henderson', 'Jessica Yu']
    -['Kim Nguyen', 'Max Martini', 'Nila Madhab Panda', 'Ian Nelms, Eshom Nelms', 'Hiroyuki Seshita', 'Lygia Barbosa da Silva, Eliane Brum', 'Osgood Perkins', 'Ken Kushner', 'Yolanda Ramke, Ben Howling', 'Kagiso Lediga']
    -['Diego Enrique Osorno', 'Hernán Zin', 'Hernán Zin', 'Hernán Zin', 'Arthur Muhammad', 'Pedring A. Lopez', 'Sam Cullman', 'Francesco Imperato', 'Stefon Bristol', 'Brit McAdams', 'Steve Loter', 'Icíar Bollaín', 'Kate Melville', 'Aditya Vikram Sengupta']
    -['David Dhawan', 'Neil Burger', 'Dibakar Banerjee', 'Apoorva Lakhia', 'Milan Luthria', 'Mandie Fletcher', 'Michael Dowse', 'Vipul Amrutlal Shah', 'Rajkumar Santoshi', 'Mercedes Cordova', 'Antonio Campos', 'Derek Cianfrance', 'Ryan Polito', 'Meenu Gaur, Farjad Nabi', 'Matthew Hope']
    -['Asim Abbasi', 'Saurabh Kabra', 'Aijaz Khan', 'Anil V. Kumar', 'Sangeeth Sivan', 'Umesh Ghadge', 'Milan Luthria', 'Apoorva Lakhia', 'Midhun Manuel Thomas', 'Neeraj Pandey', 'Umer Adil', 'Hayao Miyazaki', 'Nicolas Winding Refn']
    -['Rajiv Mehra', 'Robert Kenner', 'Kundan Shah', 'So Yong Kim', 'Alina Teodorescu', 'Rajiv Mehra', 'Filip Renc', 'Femi Oyeniran, Kalvadour Peterson', 'David Morris, Jacqui Morris', 'Gonzalo López-Gallego', 'Damián Romay']
    -['Abby Epstein', 'Savage Steve Holland', 'Tim Maltby', 'Jay Karas', 'Andy Tennant', 'Hepi Mita', 'Anthony Abrams, Adam Larson Broder', 'Dylan Bank, Daniel DiMauro, Morgan Pehme', 'Sean Foley', 'Pierre Coré', 'Che Sandoval', 'Jean-Bernard Marlin']
    -['Yee Tung-Shing', 'Raúl Campos, Jan Suter', 'Trey Borzillieri, Barbara Schroeder', 'Vince Marcello', 'Rajiv Chilaka', 'Sidheswar Shukla, Asit Mohapatra', 'Asit Mohapatra, Shyamal Chaulia', 'Shyamal Chaulia, Asit Mohapatra', 'Patricia Font', 'Amy Poehler']
    -['Sachin Kundalkar', 'Puri Jagannadh', 'Krish', 'Shoojit Sircar', 'Ribhu Dasgupta', 'Geoff Anderson', 'Federico Veiroj', 'Robert Vince', 'Mark Zwonitzer', 'Bo Welch', 'Sedat Kirtan, Kubilay Sarikaya', 'Stacia Crawford', 'Michael Epstein', 'Sudipto Roy', 'Frédéric Tonolli', 'Rachel Lears']
    -['Emmanuel Amara', 'Syamsul Yusof', 'Nicholas Winter', 'Bong Joon Ho', 'Mangesh Kanthale', 'Kevin Munroe', 'Frank Oz, Jim Henson', 'Gary Young', 'Nicanor Loreti', 'Simon Napier-Bell', 'A. L. Vijay', 'Devashish Makhija']
    -['Amal Neerad', 'Fluvio Iannuci, Roly Santos', 'Julius R. Nasso', 'Lucas Figueroa', 'Francis Lee', 'Shanker Raman', 'Rakshith Thirthahalli', 'C. Fitz', 'Alex Timbers', 'Damien Piscarel, Florent Bodin', 'Saandeep Patel', 'Justin G. Dyck']
    -['Arun Vaidyanathan', 'Pradip Kurbah', 'Alfonso Rodríguez', 'Guillermo Garcia, David Cantolla', 'Makarand Mane', 'Pierfrancesco Diliberto', 'Priyadarshan', 'Sean Menard']
    -['Dito Montiel', 'Vicente Villanueva', 'Don Michael Paul', 'Anu Menon', 'Adrian Murray', 'Andy Goddard', 'K. Rajagopal', 'Atanu Ghosh', 'Supavitra Babul', 'Zoya Akhtar, Dibakar Banerjee, Karan Johar, Anurag Kashyap', "Anthony D'Souza", 'Soumendra Padhi', 'Mahesh Bhatt', 'David Dhawan', 'Ken Burns, Artemis Joukowsky', 'Fuwad Khan']
    -['Mike Birbiglia', 'Nishikant Kamat', 'Praveen Nischol', 'Dylan Mohan Gray', 'Kabir Sadanand', "Shinji Aramaki, Mamoru Oshii, Hideki Futamura, Toshiyuki Kanno, Tomoki Kyoda, Koichi Mashimo, Yasushi Muraki, Daisuke Nishio, Frank O'Connor, Koji Sawai, Joseph Chou, Hiroshi Yamazaki", 'Justin Bare, Matthew Miele', 'Lucien Jean-Baptiste', 'Jalil Lespert', 'Sudhir Mishra', 'Edward Cotterill', 'Sean Cisterna', 'Sudhanshu Saria', 'Sarah Moshman', 'Omung Kumar']
    -['Bob Hercules, Rita Coburn Whack', 'Munish Bhardwaj', 'Dilip Mehta', 'Satish Rajwade', 'Umesh Shukla', 'Devika Bhagat', 'Luv Ranjan', 'Luv Ranjan', 'Vikas Bahl', 'Dharmesh Darshan', 'Kireet Khurana, Padmakumar Narasimhamurthy', 'Bejoy Nambiar', 'Neeraj Pandey', 'Aanand Rai', 'Isaki Lacuesta, Isa Campo', 'Gurmmeet Singh']
    -['Sangeeth Sivan', 'Nathan Landeg', 'Fernando González Molina', 'Yann Arthus-Bertrand, Michael Pitiot', 'Gonzalo López-Gallego', 'Kazuya Murata', 'Mina Shum', 'Martin Zandvliet', 'Stephen Belber', 'Tony Stone', 'Cosmo Feilding-Mellen', 'Peter Foott', 'Raam Reddy', 'Majid Al Ansari']
    -['Woody Allen', 'Ibrahim Bin Mohamed, Hasan Aljaberi', 'Clark Johnson', 'Emmanuel Mouret', 'Robert Rodriguez', 'Terry Gilliam', 'Robin Swicord', 'Conor Allyn']
    -['Uraaz Bahl', 'Frank Coraci', 'John Patrick Shanley', 'Haifaa Al-Mansour', 'Wenn V. Deramas', 'Olivia M. Lamasan', 'Antoinette Jadaone', 'Nuel Naval', 'Nicolás López', 'Paul Solet, Rick Benattar', 'Amy Schumer', 'Ian Kirby']
    -['Sean McNamara', 'Joe Camp', 'Joe Camp', 'Joe Camp', 'Michael Simon', 'Justin Chon', 'Aziz Ansari', 'David Sampliner', 'Adam Shankman', 'Chito S. Roño', 'Marc Forster', 'Keoni Waxman', 'Benny Fine', 'Mae Czarina Cruz']
    -['Onir', 'Paul Soriano', 'Wenn V. Deramas', 'Ruel S. Bayani', 'Peter Mortimer, Josh Lowell', 'Ben Wallis', 'Greg Coolidge', 'Iginio Straffi', 'Owen Egerton', 'Sam "Blitz" Bazawule', 'Norm Hiscock, Gary Howsam, Mike Smith, John Paul Tremblay, Robb Wells', 'Joe Miale', 'Dheeraj Berry', 'Richard Sears']
    -['Nirpal Bhogal', 'Laurent Bouzereau', 'Brett Whitcomb', 'Lucy van Beek', 'Frank Capra, Joris Ivens', 'John Huston', 'Jakob Verbruggen', 'George Stevens', 'Frank Capra', 'John Huston', 'John Ford', 'Charlie McDowell', 'Michael Samuels']
    -['William Wyler', 'Stuart Heisler', 'William Wyler, John Sturges', 'Frank Capra, John Huston, Hugh Stewart, Roy Boulting, Anthony Veiller', 'John Ford', 'Frank Capra, Anatole Litvak', 'John Huston', 'Micah Bickham, Galley Molina', 'Stuart Orme', 'Olivia Newman']
    -['Jared Stern', 'Yang Lei', 'Raúl Campos, Jan Suter', 'Lennart Ruff', 'Mike Clattenburg', 'Mike Clattenburg', 'Adam MacDonald', 'Saurav Palodhi', 'Shawn Crahan', 'Michael Whitton', 'Steve Carr', 'Swapnaneel Jayakar', 'Kyzza Terrazas']
    -['Miguel Conde', 'Philippe Falardeau', 'John Lee Hancock', 'Theo Love', 'Eli Craig', 'Bart Freundlich', 'Shannon Hartman', 'Awi Suryadi', 'Hanung Bramantyo', 'Óskar Thór Axelsson', 'Dan Lucchesi']
    -['Vishal Mahadkar', 'Ryan Polito', 'Mikhail Red', 'Raj Babu', 'Rodolphe Guenoden', 'Javier Ruiz Caldera', 'Dan Fraga, William Lau', 'Marina Willer', 'Diego Pignataro', "Meghan O'Hara", "Tommy O'Haver", 'Douglas McGrath', 'Chanon Yingyong, Phuwanit Pholdee']
    -['Kyle Newacheck', 'Mijke de Jong', 'Jorge Granier', 'Daryl Hannah', 'Michael Larnell', 'Advait Chandan', 'Abel Ferrara', 'Oriol Paulo', 'Stuart Sender']
    -['Jeff Tremaine', 'Paul Dugdale', 'Wenn V. Deramas', 'Joyce Bernal', 'Jason Paul Laxamana', 'Maryo J. De los Reyes', 'Chito S. Roño', 'Theodore Boborol', 'Gavin Fitzgerald', 'Juan Zapata', 'Stan Lathan', 'Gianfranco Rosi', 'Gianfranco Rosi']
    -['Oliver Daly', 'Luis Ara', 'Karan Shivajirao Chavan, Vikram Tanajirao Patil', 'Melinda Janko', 'Ram Gopal Varma', 'Tanuj Bhramar', 'Isao Yukisada', 'A.R. Murugadoss', 'A.R. Murugadoss', 'John Lee Hancock', 'Robin Swicord']
    -['Faraz Haider', 'Fritz Ofner', 'Mozez Singh', 'Raúl Campos, Jan Suter', 'Raúl Campos, Jan Suter', 'Robin Aubert', 'Brendan Toller', 'Kristian Levring', 'Mark Helenowski, Kevin Pang', 'Amy Schumer', 'Jonathan Ignatius Green', 'Sonny Marler', 'Taron Lexton', 'Robert Vince']
    -['Eva Vives', 'Lonny Price', 'Sang-ho Yeon', 'Jason Krawczyk', 'Sam Wrench', 'Sophie Robinson, Lotje Sodderland', 'John Lee', 'Richard Loncraine', 'Sydney Freeland', 'Ben Bowie, Geoff Luck', 'Jung-woo Park', 'Asghar Farhadi', 'Brandon Camp']
    -['Alison Klayman', 'Yoo Byung-jae', 'Victor Levin', 'Henry Selick', 'James Ivory', 'Gonzalo López-Gallego', 'Lone Scherfig', 'Mark Dindal', 'Pia Sukanya', 'Yann Gozlan', 'Niyi Akinmolayan', 'Francesco Imperato', 'Hoyt Yeatman']
    -['Lukas Dhont', 'Manny Rodriguez', 'Michael Simon, Matthew McNeil', 'Manny Rodriguez', 'Michael Simon', 'Stephen Chow', 'Frank W Chen', 'Adrian Teh', 'Florian Henckel von Donnersmarck', 'Steven R. Monroe']
    -['Buz Wallick', 'Indrasis Acharya', 'Aatmaram Dharne', 'Sumitra Bhave, Sunil Sukthankar', 'Sunao Katabuchi', 'Kedar Shinde', 'Johan Brisinger', 'Attila Till', 'Mahesh Manjrekar', 'Tim Bartley', 'Robyn Butler', 'John Upchurch', 'Deepika Narayan Bhardwaj']
    -['Israel Adrián Caetano, Bruno Stagnaro', 'Girish Joshi', 'Aditya Sarpotdar', 'Arjun Gourisaria, Moinak Biswas', 'Maria Sadowska', 'Santosh Sivan', 'Erik Canuel', 'Pascal Blanchard, Sonia Dauger, David Dietz', 'Heidi Saman', 'Peter Middleton, James Spinney', 'Shashilal K. Nair', 'Jayaraj Rajasekharan Nair', 'Partho Sen-Gupta']
    -['Eric Drath', 'Sam Upton', 'Maryo J. De los Reyes', 'Olivia M. Lamasan', 'Joyce Bernal', 'Theodore Boborol', 'Cathy Garcia-Molina', 'Yang Woo-seok', 'Pan Nalin', 'Shannon Hartman', 'J.C. Chandor']
    -['John L. Spencer', 'Victor Cook', 'Brian Klein', 'Devin Chanda', 'Tekin Girgin', 'David Chirchirillo', 'Marianna Palka', 'Dennis Bartok', 'Kenneth Müller', 'Marcel Barrena']
    -['Burak Aksak', 'Hakan Algül', 'Gerard McMurray', 'Muharrem Gülmez', 'Ozan Açıktan', 'Meltem Bozoflu', 'Hakan Algül', 'Selçuk Aydemir, Birkan Pusa', 'Selçuk Aydemir', 'Hakan Algül', 'Hakan Algül', 'Hakan Algül', 'Ömer Faruk Sorak', 'Şenol Sönmez', 'Ali Taner Baltacı, Cem Yılmaz']
    -['Sermiyan Midyat', 'Sermiyan Midyat', 'Aytaç Ağırlar', 'Burak Aksak', 'Kıvanç Baruönü', 'Kıvanç Baruönü', 'Yusuf Pirhasan', 'Mahsun Kırmızıgül', 'Hakan Algül', 'Kıvanç Baruönü', 'Clementine Malpas, Leslie Knott', 'Ketche', 'Erol Özlevi', 'Hakan Yonat', 'Ozan Açıktan']
    -['Olivier Loustau', 'Yılmaz Erdoğan', 'Yılmaz Erdoğan, Ömer Faruk Sorak', 'Yılmaz Erdoğan', 'Nottapon Boonprakob', 'Perry Lang', 'Nawapol Thamrongrattanarit', 'Xavier Gens', 'Gary Wheeler', 'Ang Lee', 'Tom Edmunds', 'Brant Sersen', 'Sam Liu, Frank Paur', 'Phil Morrison']
    -['Paul Katis', 'Matthew Vaughn', 'Jonathan A. Rosenbaum', 'Franck Phelizon', 'Peter Howitt', 'Matthew Atkinson', 'Rajiv Menon', 'Chiwetel Ejiofor', 'Michael Buster', 'Philip Einstein Lipski, Jørgen Lerdam, Amalie Næsby Fick', 'Rodrigo Salomón, Pietro Scappini', 'Mark Waters', 'James Toback']
    -['David Wain', 'Debra Granik', 'Miguel Ángel Vivas', 'Joey Curtis', 'Alison Klayman', 'Abbas Alibhai Burmawalla, Mastan Alibhai Burmawalla', 'Shikha Makan', 'Haissam Hussain', 'Mitch Gould', 'Kaizad Gustad', 'Ram Gopal Varma', 'Clay Porter', 'Mani Ratnam']
    -['Eeshwar Nivas', 'Hugues Nancy, Fabien Beziat', 'Indra Kumar', 'Mani Ratnam', 'Satish Kaushik', 'Tim Van Someren', 'David Dhawan', 'Shawn Arranha', 'Jonathan Baker', 'K. Subhash', 'Nagesh Kukunoor', 'V. K. Prakash', 'Manish Tiwary', 'David Dhawan', 'Kranti Redkar', 'Dhilip Kumar']
    -['Subhash Ghai', 'Surya S.J., Sunil Kumar Agrawal', 'Samir Karnik', 'Daniel Lindsay, T.J. Martin', 'Syed Ahmad Afzal', 'RZA', 'Steve Sacks', 'Mike Fetterly, Steve Sacks', 'Anees Bazmee', 'Subhash Ghai', 'Mahesh Manjrekar', 'Rajkumar Santoshi', 'Manish Gupta', 'Jeeva']
    -['K. Gopinathan', 'Lars Büchel', 'Krishna Vamshi', 'Dibakar Banerjee', 'Gurudev Bhalla', 'Samar Khan', 'Amit Barot', 'Adarsh Eshwarappa', 'Bejoy Nambiar', 'Carlo Padial', 'Indra Kumar', 'Ashutosh Gowariker', 'Mike Smith, John Paul Tremblay, Robb Wells', 'Subhash Ghai', 'Julien Seri', 'Leena Yadav']
    -['Bryan Buckley', 'Keerthi', 'Abhishek Sharma', 'Gajendra Ahire', 'Gajendra Ahire', 'Buddhadev Dasgupta', 'Mike Smith, John Paul Tremblay, Robb Wells', 'Mike Smith, John Paul Tremblay, Robb Wells', 'Mike Clattenburg', 'Mike Clattenburg', 'Mukul Anand', 'Preston A. Whitmore II', 'Milind Dhaimade', 'Ashish R. Mohan', 'N. Chandra', 'Subhash Ghai']
    -['Mani Ratnam', 'Volker Arzt, Angelika Sigl', 'Arne Birkenstock', 'Jonathan Taylor', 'Alessandro Pepe', 'Selvamani Selvaraj', 'Vijay Jayapal']
    -['Matt Wechsler', 'Hernán Belón', 'Anurag Kashyap', 'Harvey Lilley', 'Lev L. Spiro', 'Michael Polish', 'Maria Ripoll', 'Dani de la Torre', 'Oren Uziel', 'Adam Marino']
    -['Kurt Wimmer', 'Craig Johnson', 'Jeffrey Walker', 'Ulises Valencia', 'Gabriel Grieco', 'Federico Veiroj', 'Isabel Coixet', 'Grant Sputore', 'Laxman Utekar', 'Juan Antin', 'Hanno Olderdissen', 'Amar Kaushik']
    -['Reginald Hudlin', 'Grant Korgan, Brian Niles', 'Ajay Bahl', 'Kees Van Oostrum', 'Eva Trobisch', 'Tamer Bassiouni', 'Travis Zariwny', 'Corbin Bernsen', 'Asghar Farhadi', 'Shadi Ali', 'Sameh Abdulaziz', 'Mahmoud Karim', 'Walerian Borowczyk', 'Hani Hamdi', 'Wael Ihsan']
    -['Amr Arafa', 'Wael Ihsan', 'Ahmed Al-Badry', 'Mohammed El-Tahawy, Mohamed Mostafa', 'Naoko Yamada', 'Philip Marlatt', 'Scott Mosier, Yarrow Cheney', 'David Gelb', 'David Guy Levy', 'Taika Waititi', 'Saul Dibb', 'Manika Sharma', 'Mathieu Auvray', 'Marcus Raboy', 'Limbert Fabian, Brandon Oldenburg', 'Grant Heslov']
    -['Timothy Reckart', 'Sittisiri Mongkolsiri', 'Kelly Reichardt', 'Robbie Grewal', 'Jay Karas', 'Ted Geoghegan', 'Yayo Herrero', 'Juan Manuel Cotelo', 'Damani Baker', 'Lyric R. Cabral, David Felix Sutcliffe', 'Cosima Spender', 'Alfonso Serrano Maturino']
    -['Timo Tjahjanto, Kimo Stamboel', 'Johnnie To', 'Seong-hun Kim', 'Bo Burnham, Christopher Storer', 'Christopher Nolen', 'Thiagarajan Kumararaja', 'Matt Palmer', 'Raúl Campos, Jan Suter', 'Rodrigo Triana', 'Elaine McMillion Sheldon', "Federico D'Alessandro", 'Anthony Pierce']
    -['Mike Mills', 'Kate Horne', 'Roberto Girault Facha', 'Christopher Ray', 'Michel Tikhomiroff', 'Emanuel Hoss-Desmarais', 'Bong Joon Ho', 'Paul Thomas Anderson', 'Alex Díaz, Marcos Bucay', 'Fredric Lean']
    -["Bill D'Elia", 'Sujoy Ghosh', 'Peter Ramsey, Rodney Rothman, Bob Persichetti', 'Doron Paz, Yoav Paz', 'Svati Chakravarty Bhatkal', 'Rian Johnson', 'Shannon Hartman', 'Justin Kelly', 'Pablo Larraín', 'Liz Garbus', 'Kevin Bray', 'Michael James Regan', 'Aditya Kripalani']
    -['Seiji Mizushima', 'Sanjay Gupta', 'Myriam Aziza', 'Vivieno Caldinelli', 'Vivieno Caldinelli', 'Raúl Campos, Jan Suter', 'Rob Burnett', 'Jay Lyons', 'Drew Casson', 'Chris Buck, Kevin Lima', 'Charlie Siskel']
    -['Brian Knappenberger', 'Brian Smith', 'Brent Bonacorso', 'Jennifer Phang', 'Mohamed Hamdy', 'Jesse V. Johnson, Jesse Johnson', 'Gerard Barrett', 'Rene Liu', 'Geoffrey Orthwein, Andrew Sullivan', 'Jovanka Vuckovic, Annie Clark, Roxanne Benjamin, Karyn Kusama', 'Miguel Cohan, Miguel Cohan', 'Luis Alberto Restrepo, Andrés Beltrán, Jaime Rayo', 'Hideaki Anno', 'Tarek Abdel Moaty']
    -['Hideaki Anno, Kazuya Tsurumaki', 'Nitesh Tiwari', 'Ismail Farouk, Hazem Fouda', 'Khaled Marei', 'Abhijit Kokate, Srivinay Salian', 'Husam El-Gohari', 'Magdy Al-Hawwary', 'Ahmad El-Badri', 'Antonin Baudry', 'Mohamed Hamdy', 'Sherif Mandour', 'Ken Burns, Lynn Novick', 'Atul Malhotra']
    -['Roy Burdine, Johnny Castuciano', 'Scott Moran', 'George Clooney', 'Datta Mohan Bhandare', 'Kieran Darcy-Smith', 'Tom Hooper', 'Salvador Calvo', 'Jun-seong Kim', 'Chris Robinson', 'Janet Tobias, Claus Wehlisch', 'David L. Cunningham']
    -['Petra Costa', 'Ed Lilly', 'Madeleine Parry, Jon Olb', 'Isaac Ezban', 'Jay Karas', 'Anirban Majumder', 'Scott Martin', 'Jeremy Kenyon Lockyer Corbell', 'Rajiv Chilaka', 'Anirban Majumder', 'Sumit Das', 'George Mendeluk']
    -['Wilson Yip', 'Kyle Patrick Alvarez', 'Jon Watts', 'Jakob Lass', 'Jay Bulger', 'Kevin Derek', 'Kip Andersen, Keegan Kuhn', 'Shazia Javed', 'John Haptas, Kristine Samuelson', 'Sanjay Jadhav', 'Ahmed El Gendy', 'Vinod Kapri']
    -['Elías León', 'Israel Adrián Caetano', 'Anders Falck, Stinus Morell Vithner', 'Zoya Akhtar, Karan Johar, Anurag Kashyap, Dibakar Banerjee', 'Oded Raz', 'Mariana Tschudi, Héctor Gálvez', 'Claire Scanlon', 'Ramón Salazar', 'Eduardo Mendoza de Echave', 'Henrik Martin Dahlsbakken', 'Arun Chidambaram', 'Caio Cobra', 'Tomer Heymann']
    -['Alex Infascelli', 'Cal Seville', 'Peggy Holmes', 'Bruno Garotti', 'Kyle Newacheck', 'Zachary Heinzerling', 'Abdul Aziz Hashad', 'Khaled Marei', 'Mark Ritchie', 'Mahmoud Karim', 'Rocky Soraya']
    -['Sameh Abdulaziz', 'Tarek Al Eryan', 'Hadi El Bagoury', 'Patrik Syversen', 'Michael John Warren', 'Andy Capper', 'Shannon Hartman', 'Martin Scorsese', 'Waymon Boone', 'Phil Johnston, Rich Moore', 'Julie Dash', 'Andrew C. Erin']
    -['Chang-Min Lee', 'Derek Yee', 'Cristina Jacob', 'Cristina Jacob', 'Roland Emmerich', 'Jonathan Levine', 'David McCracken', 'Brian De Palma', 'Sanjib Dey', 'Ron Davis', 'Cristina Jacob']
    -['Cristina Jacob', 'Barry Avrich', 'Jon Avnet', 'V. Scott Balcerek', 'Joe Dante', 'Richard Kelly', 'Joel Schumacher', 'Peter Chelsom', 'Peter Hutchings', 'Daniel Yee Heng Chan', 'Dennie Gordon', 'Shadab Khan', 'Nattawut Poonpiriya', 'Elvira Lind', 'Davis Guggenheim']
    -["Gavin O'Connor", 'Jon Turteltaub', 'Mahesh Manjrekar', 'Lynn Shelton', 'Felix Starck', 'Robert Kouba', 'Umesh Mehra', 'Edward Cotterill', 'Ted Braun', 'Jon Manning', 'Onur Tukel', 'Luis Lopez', 'Saara Cantell', 'Ron Howard']
    -['Cal Seville', 'Edward Cotterill', 'Jayaprakash Radhakrishnan', 'Rob Meyer', 'Anita Barbosa', 'Ketan Mehta', 'Daniel Wilner', 'Ketan Mehta', 'Lekh Tandon', 'Umesh Mehra']
    -['Alberto Rodríguez', 'Edward Cotterill', 'Alfonso Cuarón', 'Jose Manuel Colón', 'Javier Ruiz Caldera', 'David Sington', 'Zoe Berriatúa', 'Luis Estrada', 'Spike Jonze']
    -['Rob Marshall', 'Lee Eung-bok', 'Karyn Kusama', 'Phyllida Lloyd', 'Leif Tilden', 'Pat Healy', 'Dustin McKenzie, Andrew Duncan, Audu Paden', 'Fabio Grassadonia, Antonio Piazza', 'Raúl Campos, Jan Suter']
    -['Jody Hill', 'Samu Fuentes', 'Alexandre Espigares', 'Suhas Kadav', 'Dan Harris', 'Qaushiq Mukherjee', 'Marcelo Altmark, Mariano Mucci, Luis A. Scalella', 'Derek Cianfrance', 'Anurag Basu', 'Michèle Ohayon', 'Renny Harlin', 'Kevin Layne']
    -['Amanda Micheli', 'Eric Khoo', 'Gideon Raff', 'Kang Cheng, Shan Hua', 'Cheh Chang', 'Nizar Shafi', 'Víctor García', 'Wilson Coneybeare', 'Marcus Raboy', 'Note Chern-Yim', 'Note Chern-Yim', 'Poj Arnon', 'Fernando Sariñana, José Luis Gutiérrez']
    -['Jonathan Levine', 'Scott L. Montoya', 'Scott L. Montoya', 'Marcus Raboy', 'David Blair', 'Kirk De Micco, Chris Sanders', 'Spike Jonze', 'Sian Heder', 'Ted Emery', 'Ted Emery', 'John Wells', 'Meng Hua Ho', 'Tony Datis', 'Vanessa Roth']
    -['Ben Ryder', 'Jim Strouse', 'Raúl Campos, Jan Suter', 'Ben Young', 'Kirby Dick', 'Raymond Wood', 'Jorge M. Fontana', 'Mikhail Red', 'Olivier Afonso', 'James Woodroffe', 'Rachel Bell']
    -['David Leveaux', 'Sebastián Schindel', 'Asif Kapadia', 'Kyle Newman', 'Gilles Paquet-Brenner', 'Alex Garland', 'Keanu Reeves', 'Anna Boden, Ryan Fleck', 'William Monahan', 'Piti Jaturaphat', 'Atom Egoyan', 'John Maclean', 'James Ponsoldt', 'Tanit Jitnukul']
    -['Atsajun Sattakovit', 'Poj Arnon', 'Poj Arnon', 'Poj Arnon', 'Abhishek Sharma', 'Note Chern-Yim', 'Sukum Maetawanitch', 'Tiffanie Hsu', 'Daniel Gray Longino', 'Nick Gomez', 'Karim Amer, Jehane Noujaim', 'Steve Paley', 'Daniel Calparsoro', 'Kevin Smith', 'Kasper Collin', 'Brandon Dickerson']
    -['Harvey Lowry', 'William Friedkin', 'Quentin Tarantino', 'Paul Andrew Williams', 'J.C. Chandor', 'Byron Howard, Chris Williams', 'Dharmesh Darshan', 'Benny Chan', 'Jay Chapman', 'Jay Karas, Demetri Martin', 'Dante Lam', 'Chi Keung Fung', 'Corey Yuen, Patrick Leung']
    -['To-hoi Kong', 'Jeff Baena', 'Andrew Lau Wai-Keung, Andrew Loo', 'Pete Travis', 'Michael Gallagher', 'Hassan Hegazy, Shady Ali', 'Chris Jenkins', 'Alexandre Avancini', 'Atom Egoyan', 'Ziga Virc']
    -['Jeffrey Walker', 'Sam Voutas', 'Alexander Nevsky', 'Frank Ariza', 'Jacob Schwab', 'Alphonso J. Wesson', 'Gillian Robespierre', 'Lenny Abrahamson', 'Lynn Shelton']
    -['Julius Avery', 'David Michôd', 'Orson Welles', 'Peter Sullivan', 'Destin Daniel Cretton', 'Alexis Morante', 'Kobun Shizuno, Hiroyuki Seshita', 'Fazila Allana', 'Eric Abrams', 'Peter Svatek', 'Aditya Sarpotdar', 'Hiromasa Yonebayashi', 'Agustí Villaronga']
    -['Kristina Goolsby, Ashley York', 'Nisheeta Keni', 'Daniel Gray Longino', 'Harvey Glazer, Stuart Stone', 'Peyton Reed', 'Ron Clements, John Musker', 'Chris Stokes', 'Steven Fine', 'Roman Coppola', 'Denis Villeneuve', 'Alejandro Doria']
    -['Heber Cannon', 'Sally Potter', 'Clay Glen', 'Steven Knight', 'Ana Quiroga', 'Harmony Korine', 'Jean-Cosme Delaloye', 'Santosh Sivan', 'Natalia Garagiola', 'Pamela Romanowsky', 'James Ponsoldt', 'Jonathan Glazer', 'Esteban Crespo', 'Anil Sharma', 'Ganesh Kadam']
    -['Anthony Scott Burns, Nicholas McCarthy, Adam Egypt Mortimer, Gary Shore, Kevin Smith, Sarah Adina Smith, Scott Stewart, Kevin Kolsch, Dennis Widmyer', 'Ticoy Rodriguez', 'Karl Mueller', 'Joe Berlinger', 'Philipp Stölzl', 'Michael Curtiz', 'Florian Gallenberger', 'Harry Chaskin', 'Jeff Orlowski', 'Marti Noxon', 'Allan Ungar', 'Patrick Brice', 'Christophe Honoré']
    -['David M. Rosenthal', 'Scott Zabielski', 'Leslie Small, Tim Story', 'Diego Cohen', 'William Eubank, Will Eubank', 'Jay Chapman', 'John Dower', 'Jay Chapman', 'Gerardo Olivares', 'Mark Harris', 'Wi Ding Ho']
    -['Thomas Sieben', 'Joe Lynch', 'Noam Murro', 'Andreas Pichler', 'Neslihan Yesilyurt']
    -['Daniel Arasanz', 'Joseph Martin', 'Chapman Way, Maclain Way', 'Sylvie Verheyde', 'Kasper Barfoed', 'Phil Joanou', 'Martin Scorsese', 'Courtney Hunt', 'Iain Softley', 'Linda Mendoza', 'Jonathan Hensleigh']
    -['M. Night Shyamalan', 'Richard Greenberg', 'Nathan Morlando', 'Martin Scorsese', 'Lee Tamahori', 'George C. Wolfe', 'Rushmore DeNooyer', 'Martin Gorst', 'Giulia Clark', 'Sarah Holt', 'Terri Randall', 'Doug Hamilton', 'Martin Gorst', 'Peter Fison']
    -['Graham Townsley', 'Paula Apsell, Kirk Wolfinger', 'Oliver Twinch', 'Oliver Twinch', 'Llewellyn M. Smith', 'Daniel McCabe', 'Peter Yost', 'Tom Stubberfield', 'Noel Dockstader, Quinn Kanaly', 'Gail Willumsen', 'Steve Carr', 'Jonathan Demme', 'Andy Fickman', 'Barry Levinson']
    -['Max Lang, Jani Lachauer', 'Wes Craven', 'Robert Rodriguez', 'David Allensworth, Monière', 'Todd Phillips', 'Ann Deborah Fishman', 'Dominic Sena', 'Martin Scorsese', 'Ryu Jung-woo', 'Matthew Shoychet', 'Albert Hughes, Allen Hughes', 'Terry Gilliam', 'Rob Minkoff', 'Andrew Fleming']
    -['Shawn Levy', 'Hernán Zin', 'Martin Scorsese', 'Lijo Jose Pellissery', 'Raj Kaushal', 'Bo Burnham, Christopher Storer', 'Noushad', 'Aziz Mirza', 'Anuranjan Premji', 'Jason Bourque', 'Johnson Esthappan', 'K.C. Bokadia', 'Greg MacGillivray', 'Miguel Arteta']
    -['P.K. Baaburaaj', 'Nila Madhab Panda', 'Vineeth Anil', 'Katherine Brooks', 'Jayan Vannery', 'Bob Odenkirk', 'Samir Soni', 'Vipul Amrutlal Shah', 'Chandran Narikode', 'Gafoor Y. Elliyaas', 'Dileep Narayanan', 'Paritosh Painter', 'Venugopan', 'Jay Chou', 'Imtiaz Ali']
    -['Juan Antonio de la Riva', 'Jenée LaMarque', 'Michael Radford', 'Heber Cannon, Mariah Moore, Marston Sawyers', 'Saheed Arafath', 'Jeffrey Nachmanoff', 'Kabir Sadanand', 'P.T. Kunju Muhammad', 'Greg MacGillivray', 'Huang Lei', 'Bert Marcus, Cyrus Saidi', 'Shlok Sharma', 'Adam Deyoe', 'Nicolas Brossette', 'Serdar Akar', 'Clay Glen']
    -['Castille Landon', 'Lekh Tandon', 'Martin Hodara', 'Vivieno Caldinelli', 'Doesjka van Hoogdalem', 'Rod Blackhurst', 'Asim Raza', 'Sushil Majumdar', 'Geetu Mohandas']
    -['Abbas Alibhai Burmawalla, Mastan Alibhai Burmawalla', 'Lekh Tandon', 'Paulo Oriol', 'Li Jun', 'Bilal Lashari', 'Yasir Nawaz', 'Umesh Mehra', 'Oskar Santos']
    -['Anders Sømme Hammer, Marius Arnesen, Klaus Erik Okstad, Olav Njaastad', 'Ryan Polito', 'Felix Thompson', 'Ishaya Bako', 'Ola Flyum, David Hebditch', 'Benny Fredman', 'Hemant Gaba, Pratim D. Gupta, Sudhish Kamath, Nalan Kumarasamy, Anu Menon, Sandeep Mohan, Qaushiq Mukherjee, Rajshree Ojha, Raja Sen, Abhinav Shiv Tiwari, Suparn Verma', 'Ivona Juka', 'Don Michael Paul', 'Mark Sloper', 'Kobun Shizuno, Hiroyuki Seshita', 'Kunal Kohli']
    -['Ron Howard', 'Ron Howard', 'Bryan Bertino', 'J. Michael Long', 'Milind Rau', 'Nick Broomfield', 'James Wan', 'Jay Karas', 'David Lowery', 'Maria Ripoll', 'Florian Henckel von Donnersmarck', 'Aaron Hancox, Michael McNamara', 'Noor Imran Mithu', 'Paakhi Tyrewala']
    -['Barbara Kopple', 'Babak Anvari', 'Sandy Chronopoulos', 'Emily Hagins', 'Eric Juhola', 'Greg Richardson', 'Dharmendra Suresh Desai', 'Iman Brotoseno', 'Anggy Umbara', 'Garin Nugroho', 'Sridhar Jetty', 'Clive Tonge', 'Nonzee Nimibutr', 'Hanung Bramantyo', 'Mike Flanagan', 'Masaaki Yuasa']
    -['Mahin Ibrahim, Austin Kolodney, Will Lowell, David Beier, Dave Dorsey, Xu Zhang, Alana Waksman, Jon YonKondy, Drue Metz, Brandon Somerhalder', 'José Eduardo Belmonte', 'Hans Petter Moland', 'Uwe Boll', 'Ísold Uggadóttir', 'Lorena Munoz', 'Genevieve Nnaji', 'Mitch Schauer', 'Terry Loane', 'Mamat Khalid', 'Maria Demeshkina Peek']
    -['Pang Ho-cheung', 'Mario Mattei', 'Lasse Hallström', 'Selima Taibi', 'Jay Karas', 'Alejandra Márquez Abella', 'Amarjit Virdi', 'Kamal Sahani', 'Dan Kwan, Daniel Scheinert', 'Brad Bird', 'Fred Durst', 'Pankaj Batra', 'Marty Callner', 'William Lau, Sylvain Blais']
    -['Yibrán Asuad', 'Anees Bazmee', 'John Hughes', 'Luke Sparke', 'Wim Wenders', 'Lance Bangs', 'Peyton Reed', 'Nishil Sheth', 'Manny Rodriguez', 'Byun Hyuk', 'Zoe Berriatúa', 'Javier Ambrossi, Javier Calvo', 'Federico Lemos', 'Jeremy Kenyon Lockyer Corbell']
    -['Peter Nicks', 'Sébastien Betbeder', 'Adam Bhala Lough', 'Faozan Rizal', 'Mansore', 'Hanung Bramantyo', 'Kuntz Agus', 'Hanung Bramantyo, Meisa Felaroze', 'Alastair Fothergill', 'Adam Randall']
    -['Nick Broomfield', 'Jerrold Tarog', 'David Wain', 'Michael McKay', 'Alexandre Heboyan, Benoît Philippon', 'Raúl Campos, Jan Suter', 'Laura Alvea, José Ortuño', 'Kim Seong-hun', 'Gastón Duprat']
    -['Isaac Florentine', 'Marco Dutra', 'Genndy Tartakovsky', 'Andy Caballero, Diego Corsini', 'July Hygreck', 'Raúl Campos, Jan Suter', 'Paul Shoulberg', 'Marcus Raboy', 'Greg Whiteley', 'Seren Yüce', 'Jorge Blanco', 'Law Wing-cheong', 'Dash Shaw', 'Scott Moran']
    -
    -
    - -
    - -
    -
    100%|██████████| 390/390 [00:00<00:00, 1009.41it/s]
    -
    -
    - -
    - -
    -
    -['Mario Rouleau', 'Santiago Diaz, Pablo Martin Farina', 'Scott Zabielski', 'Raúl Campos, Jan Suter', 'Ahmed Khaled Moussa', 'Néstor Sánchez Sotelo', 'Aniruddha Roy Chowdhury', 'Chester Tam', 'Mohit Suri']
    -['Terry Gilliam, Terry Jones', 'Jon Schnitzer', 'Craig Elrod', 'Benjamin Cohen, Nicolas Cotto', 'Mike Rossiter', 'Michael McKay', 'Charles Stone III', 'Matt Angel, Suzanne Coote', 'Chris McCoy', 'Sofia Coppola', 'Chris Smith', 'Jonathan Helpert']
    -["André D'Elia", 'Matías Gueilburt', 'Ivan Ayr', 'Chris Baugh', 'Jenny Carchman', 'Tyler Perry', 'Raúl Campos, Jan Suter', 'Kobun Shizuno, Hiroyuki Seshita', 'Neal Brennan', 'G.J. Echternkamp']
    -['Jehane Noujaim', 'Caryn Waechter', 'Nicholas Stoller', 'Tim Hill', 'Numa Perrier', 'Brian Helgeland', 'Yoshiyuki Momose', 'Danny Boyle', 'Colin Strause, Greg Strause', 'Ethan Coen, Joel Coen', 'Jean-Marc Vallée', 'Marc Abraham', 'Steve Barker']
    -['Shawn Levy', 'Rima Das', 'Paco Plaza', 'Andrew Goth', 'Jeffrey G. Hunt', 'William Kaufman', 'Marek Kanievska', 'Skye Borgman', 'Hashim Nadeem Khan', 'Mohsin Ali', 'Svetlana Cvetko', 'Sarjun', 'Alejandro Lozano']
    -['Michael Civille', 'Feroz', 'Syed Atif Ali', 'Lee Seung-won', 'Rik Reinholdtsen', 'Stephanie Soechtig, Jeremy Seifert', 'Rocky Soraya', 'Rocky Soraya', 'John Asher', 'Latif Faiziyev, Umesh Mehra', 'M.J. Isakson', 'Matt Toronto', 'Michael Roberts', 'Noah Moskin', 'John H. Lee']
    -['Ajay Bhuyan, Kunal Kohli', 'Rajiv Mehra', 'Rhiannon Bannenberg', 'Bin Bunluerit', 'Jennifer Brea', 'Pradeep Verma', 'Hannes Stöhr', 'Ron Davis', 'Marty Stalker', 'Daniel Noah', 'Andreas Prochaska', 'Maximilian Erlenwein', 'John Carchietta', 'Isaac Ezban', 'Burhan Qurbani']
    -['Wilson Yip', 'Wilson Yip', 'David Benioff, D.B. Weiss', 'Paul Thomas Anderson', 'Patryk Vega', 'Charles Officer', 'Peter Sattler', 'Marcelo González', 'Zach Clark', 'N.D. Wilson', 'Sean Penn', 'Daniel Stamm', 'Gauravv K Chawla']
    -['David O. Russell', 'Kleber Mendonça Filho', 'Hubert Woroniecki', 'Alistair Legrand', 'Steve Boettcher', 'Mikhil Musale', 'Julian Jarrold', 'Quinn Lasher', 'David Mrnka', 'John Mikulak, Joshua Brown', 'Maya Forbes', 'Choi Jin-seong', 'Jay Karas', 'Ira Sachs', 'Mir-Jean Bou Chaaya']
    -['Peter Hewitt', 'Dan Villegas', 'Bent-Jorgen Perlmutt', 'Hugo Stuven', 'Greg Pritikin', 'Amman Abbasi', 'Soumendra Padhi', 'Tom Green', 'Mike Gunther', 'Fred Olen Ray', 'Sam Raimi']
    -['Johannes Roberts', 'Heitor Dhalia', 'Jeannie Gaffigan', 'Robert Luketic', 'Mark Rosman', 'Richard Rich', 'Sam Mendes', 'Sarah Smith', 'Edwin', 'James L. Brooks', 'Jeff Tremaine']
    -['Vadim Jean', 'Steven Spielberg', 'Nicholas Hytner', 'Tim Burton', 'Kevin Smith', 'Ken Hughes', 'Atom Egoyan', 'Fernando Meirelles, Katia Lund', 'Frank Coraci', 'Matt Reeves', 'Thomas Carter', 'Jay Roach', 'Mike Newell']
    -['Rob Cohen', 'Colin Teague', 'Doug Lefler', 'Paul W.S. Anderson', 'Chris Stokes', 'James Wong', 'David R. Ellis', 'James Wong', 'Simon Wincer', 'Marcus Nispel', 'Mark A.Z. Dippé, Kyung Ho Lee', 'Mark A.Z. Dippé, Eondeok Han', 'Mark A.Z. Dippé', 'Mark Steven Johnson', 'Anurag Kashyap, Dibakar Banerjee, Karan Johar, Zoya Akhtar', 'Roland Emmerich']
    -['Adam Shankman', 'Danny Leiner', 'Andy Tennant', 'Keoni Waxman', 'Christopher Nolan', 'Eugenio Derbez', 'Michael Simon', 'John A. Davis', 'Nora Ephron', 'James Mangold', 'Quentin Tarantino', 'Quentin Tarantino', 'Peter Farrelly, Bobby Farrelly', 'Gary Fleder', 'Luis Valdez', 'Zack Snyder']
    -['Lucas Margutti', 'Paul Thomas Anderson', 'Shyam Benegal', 'Patricia Rozema', 'Robert Luketic', 'Duncan Jones', 'Howard Zieff', 'Dennie Gordon', 'Justin Webster', 'Guillermo del Toro', 'Oren Peli', 'Phillip Noyce', 'Tetsuo Yajima', 'Edwin']
    -['Paul W.S. Anderson', 'John Lyde', 'Steve Rash', 'Keenen Ivory Wayans', 'John Stockwell', 'Gregg Bishop', 'Phillip Noyce', 'Chris Koch', 'Baz Luhrmann', 'Rob Minkoff', 'Rob Minkoff', 'Tim Burton', 'Michael Pressman']
    -['Steve Barron', 'Jonathan Mostow', 'McG', 'Andrew Douglas', 'Andrew Fleming', 'Neil Jordan', 'Jay Chandrasekhar', 'Robert Berlinger', 'David R. Ellis', 'Ricky Gervais, Matthew Robinson', 'Peter Jackson', 'Peter Jackson', 'Martin Campbell', 'David Zucker']
    -['David Zucker', 'Barry Levinson', 'Spike Lee', 'Mimi Leder', 'Gore Verbinski', 'Anthony Minghella', 'Ron Underwood', 'S.S. Wilson', 'Brent Maddock', 'S.S. Wilson', 'Don Michael Paul', 'Henry Hathaway', 'Jason Reitman', 'Robert Zemeckis', 'Barry Sonnenfeld', 'Mel Stuart']
    -['Lawrence Kasdan', 'Peyton Reed', 'Nicole Conn', 'Julie Taymor', 'Alejandro G. Iñárritu', 'Yanyong Kuruaungkoul', 'Ridley Scott', 'Neill Blomkamp', 'Joe Roth', 'Steve Carr', 'Mark Landre Gould', 'David Mackenzie', 'Steven Spielberg', 'Steven Spielberg', 'Steven Spielberg']
    -['Steven Spielberg', 'Kevin Smith', 'Clint Eastwood', 'Lori Kaye', 'William H. Macy', 'Massy Tadjedin', 'Guy Ritchie', 'Lenin Bharathi', 'Mike Newell', 'Jay Chapman', 'James Foley', 'Kunihiko Yuyama', 'Quentin Tarantino', 'Ranjit Jeyakodi', 'Ram', 'Antoine Fuqua']
    -['Mark Herman', 'Alex Proyas', 'Ben A. Williams', 'Stephen Daldry', 'John Fortenberry', 'Rob Cohen', 'Lee Tamahori', 'Chandrakant Kulkarni', 'Uttung Shelar', 'Greg Kohs', 'Sumitra Bhave, Sunil Sukthankar', 'Lisa Arnold', 'Bedabrata Pain', 'Sumitra Bhave, Sunil Sukthankar', 'Reiner Holzemer']
    -['Kim Nguyen', 'Jose Manuel Colón', 'Nagraj Manjule', 'Bob Rose', 'Abba T. Makama', 'Joe Dietsch, Louie Gibson', 'Chris Sivertson', 'Amar Gupte', 'Sooraj R. Barjatya', 'Sooraj R. Barjatya', 'Sachin', 'Amardeep Singh Gill', 'Jon M. Chu', 'Chandrakant Kulkarni', 'Pratim D. Gupta']
    -['Ben Patterson', 'Sooraj R. Barjatya', 'David Batty', 'Sachin', 'Santosh Manjrekar', 'Steve Ball, Andrew Duncan', 'Dustin McKenzie', 'Victor Dal Chele, Alfred Gimeno', 'William Lau', 'Dustin McKenzie, Steve Sacks', 'Kiki Goshay, Jacqueline Monetta', 'Peter Pardini', 'Lars von Trier', 'Rebecca Zlotowski', 'René Pérez Joglar']
    -['Rajeev Patil', 'Sudesh Manjrekar', 'Kevin Phillips', 'Jee-woon Kim', 'Niyi Akinmolayan', 'Satish Manwar', 'Alison MacLean', 'David Koepp', 'Dan Bush', 'Sameer Vidwans', 'Sam Hobkinson', 'Kedar Shinde', 'Karan Bali']
    -['Rohit Mittal', 'Steve Hickner, Simon J. Smith', 'Jalil Lespert', 'Matt Kugelman', 'Hari Viswanath', 'Pratim D. Gupta', 'Pieter-Jan De Pue', 'Miriam Chandy Menacherry', 'Edward Ellis, Flor Salcedo, Aaron Woolf', 'Abhishek Chaubey']
    -['Jerry Rothwell']
    -['Charlie Haskell, Koichi Sakamoto', 'James Barr', 'Sorin Dan Mihalcescu', 'Harold Cronk']
    -['Roberta Grossman, Sophie Sartain', 'David Bruckner', 'Tamta Gabrichidze', 'Ari Sandel', 'Caradog W. James', 'Steven Soderbergh', 'Brad Bird', 'Tom Stern', 'Kelly Duane de la Vega', 'Julio Medem', 'Toa Fraser', 'Deane Taylor']
    -['Luis Javier M. Henaine', 'Mathias Malzieu, Stéphane Berla', 'Jenna Laurenzo', 'Scott Aukerman, Akiva Schaffer', 'Hark Tsui', 'Bob Nelson', 'Lance Bangs', 'Trevor Ryan', 'Alex Zamm', 'Charles Stone III', 'Michael Showalter']
    -['Stephen Cone', 'Julius Onah', 'Jordan Ross', 'Krishna Agazzi, Filippo Gastaldi', 'Alison E. Rose', 'Roland Joffé', 'Lance Bangs', 'Philipp Stölzl', 'Craig Moss', 'Wade Allain-Marcus, Jesse Allain-Marcus']
    -['Raúl Campos, Jan Suter', 'Malik Vitthal', 'Vonda Harrell, Daniel Camenisch', 'Fabio Guaglione, Fabio Resinaro', 'Carlos Vermut', 'Shaina Allen', 'Joey Kern', 'Hong-seon Kim', 'Lilibet Foster', 'Seth Barrish, Mike Birbiglia', 'J.C. Falcón', 'Cathy Garcia-Molina', 'Wenn V. Deramas', 'Mae Czarina Cruz', 'Mae Czarina Cruz', 'Sridhar Rangayan']
    -['Cathy Garcia-Molina', 'Wenn V. Deramas', 'Cathy Garcia-Molina', 'Cathy Garcia-Molina', 'Saw Teong Hin, Nik Amir Mustapha, M.S. Prem Nath', 'Cathy Garcia-Molina', 'Dan Villegas', 'Olivia M. Lamasan', 'Wenn V. Deramas', 'Cathy Garcia-Molina', 'Antoinette Jadaone', 'Marcus Raboy', 'Abhinay Deo', 'John Asher']
    -['Jesse Peretz', 'Michael Blieden', 'Sherwin Shilati', 'Mark Columbus, Lauren Hoekstra, Sarah Kruchowski, Ryan Moody, Simon Savelyev, Vanita Shastry, Shadae Lamar Smith, Jeremy David White', 'Dejan Zečević', 'Pascale Lamche', 'Lô Politi', 'Yuen Wo-Ping', 'Joshua Oppenheimer', 'Jeremy Saulnier', 'Charles Martin Smith', 'Pawan K Shrivastava', 'Paco Plaza', 'Tomas Portella']
    -['Kazuchika Kise, Masahiko Murata', 'Kazuchika Kise', 'Kazuchika Kise', 'Macon Blair', 'Mitch Schauer', 'Mar Targarona', 'Duncan Jones', 'Steven Gomez', 'Robert Cannan, Ross Adam', 'Ryan Polito']
    -['Aruna Raje', 'Alex Lehmann', 'Elisabeth Vogler', 'Parambrata Chatterjee', 'Brian A. Miller', 'Errol Morris', 'Adam Smith', 'Ken Burns', 'Ken Burns', 'Benjamin Ree', 'Susannah Ward', 'Sam Taplin', 'Kasia Uscinska', 'Vicky Matthews']
    -['Vicky Matthews', 'Woo Min-ho', 'Femi Oyeniran, Nicky Slimting Walker', 'Hang-Jun Jang', 'Steven Spielberg', 'Kurt Voelker', 'David Paul Meyer', 'Constance Marks', 'Paul Miller', 'Michael Del Monte', 'Andreas Johnsen', 'Nora Twomey', 'Rakeysh Omprakash Mehra', 'Chris Blake', 'Johnny Kevorkian']
    -['Amshan Kumar', 'David L.G. Hughes', 'Michael McKay', 'Ildiko Enyedi', 'You-Jeong Chang', 'Richard Bates Jr.', 'Steve McLean', 'Robert Rodriguez', 'Gregory Caruso', 'Benjamin Arfmann', 'Fumihiko Sori', 'Shin-yeon Won']
    -['Mar Targarona', 'Keith Scholey', 'Juan Pablo Buscarini', 'Keiichi Sato, Yasushi Kawamura', 'Chad Van De Keere', 'Chad Van De Keere', 'Suseenthiran', 'Lucky McKee', 'Cecilia Peck', 'Sanjeev Gupta', 'Paul Tanter', 'Nishikant Kamat']
    -['Nishikant Kamat', 'Ribhu Dasgupta', 'Kevin MacDonald', 'Matt Tyrnauer', 'Stephan Rick', 'Mariano Baez', 'Stephanie Laing', 'Gus Van Sant', 'Logan Kibens', 'Leo Riley, Eric Radomski', 'Vincent Perez', 'Ozan Açıktan', 'Carlos Marques-Marcet', 'Prasanth Varma']
    -['Gangadhar Salimath', 'Daniel J. Clark', 'Marcelo Galvão', 'Shanawaz Nellikunnil', 'Sudhir Mishra', 'Danny J. Boyle', 'Rajat Kapoor', 'Lars Kaalund', 'Bedran Güzel', 'Hari Nath', 'Josh Webber', 'Adam Collins, Luke Radford', 'Saket Chaudhary', 'Tanuja Chandra']
    -['Jackie van Beek, Madeleine Sami', 'Blair Hayes', 'Sachin Kamlakar Khot', 'Tolga Örnek', 'Daniel Monzón', 'Sung-soo Kim', 'Chandrakant Kanse', 'Sanjay Jadhav', 'Sudesh Manjrekar, Atul Kale', 'Avadhoot Gupte', 'Satish Rajwade', 'Sanjay Soorkar']
    -['Gajendra Ahire', 'Michael J. Bassett', 'Chandrakant Kulkarni', 'Avadhoot Gupte', 'Thomas Stuber', 'Christopher Chambers', 'Giulio Base', 'Sam Dunn, Scot McFadyen', 'Raúl Arévalo', 'Matías Bize', 'Alex Holmes', 'Tanuj Chopra', 'Jon M. Chu']
    -['Bo Burnham', 'Anand Tiwari', 'Michael Paul Stephenson', 'Colin Dench', 'Jesús Magaña Vázquez', 'Corey Grant', 'Gareth Evans', 'Shaul Schwarz, Christina Clusiau', 'Rayka Zehtabchi', 'Jevons Au, Zune Kwok, Chow Kwun-wai, Ng Ka-Leung, Wong Fei-Pang', 'Olivier Assayas', 'Jeremiah Zagar', 'Afonso Poyart']
    -['Ricky Gervais', 'Joachim Fest, Christian Herrendoerfer', 'Joe Berlinger, Bruce Sinofsky', 'Adam Davis, Jerry Kolber, Trey Nelson, Erich Sturm', 'Chris Weitz, Paul Weitz', 'Stephen Daldry', 'Brad Peyton', 'Hsu Chih-yen, Mag Hsu', 'Emma Hatherley', 'Meghna Gulzar']
    -['Eddie Martin', 'Kelly Noonan', 'Rick Morales', 'Andrew Tan, Stephen Murray', 'Michael D. Black', 'Michael Winnick', 'James McTeigue', 'Olivier Assayas']
    -['Kelly Fremon Craig', 'Kyle Rankin', 'Pramod Pawar', 'Dan Gilroy', 'Rebecca Harrison', 'Milla Harrison-Hansley, Alicky Sussman', 'Storm Theunissen', 'Jack C. Newell']
    -['Karyn Kusama', 'Fisher Stevens', 'Neil Triffett', "Tom O'Dell", 'John Trengove', 'Ui-seok Jo', 'Michael Mayer', 'Greg MacGillivray', 'Drake Doremus', 'Amber Tamblyn', 'Jani Lachauer, Jakob Schuh']
    -['Marina Zenovich', 'Carlos Bolado', 'Gurvinder Singh', 'Rohit Shetty', 'Anjali Nayar', 'Farah Khan', 'Shlok Sharma', 'Joaquín Mazón', 'Scott Hicks', 'Adam Sjöberg', 'John Stewart Muller', 'Leandro Mark, Nicolás Silbert', 'Pulkit', 'Jennie Livingston', 'Oscar Micheaux, Spencer Williams, Richard E. Norman, Richard Maurice']
    -['Vlad Yudin', 'Jonás Trueba', 'Peter DeLuise', 'Robbie Countryman', 'Trey Edward Shults', 'Jason James', 'James Yukich', 'Nic Mathieu', 'Gary Howsam, Mike Smith, John Paul Tremblay, Robb Wells', 'Pierre Morel', 'Sujeeth']
    -['Agasyah Karim, Khalid Kashogi', 'Jonathan Sobol', 'Ifa Isfansyah', 'Nia Dinata', 'Rudy Soedjarwo, Riri Riza', 'Abhinay Deo', 'Kiran Rao', 'David E. Talbert', 'Umesh Mehra', 'Abbas Tyrewala', 'Ashutosh Gowariker', 'Bhagyaraj', 'Anusha Rizvi, Mahmood Farooqui', 'Latif Faiziyev, Umesh Mehra', 'Aamir Khan', 'Baltasar Kormákur']
    -['John Stockwell', 'Chris Kelly', 'Karey Kirkpatrick', 'Alexandre Avancini', 'Marco Risi', 'Anne Fletcher', 'Marek Losey', 'Andy Serkis', 'Mat King', 'Brian Oakes', 'Jacob Joice', 'Bert Marcus', 'Drew Heriot']
    -['BB Sasore', 'Pascal Amanfo', 'Noah Baumbach', 'Atsuko Ishizuka', 'Eric Aghimien', 'Robert Kenner, Taki Oldham', 'Bruce Robinson', 'Omoni Oboli', 'Omoni Oboli']
    -['Saratswadee Wongsomphet', 'Joel Crawford', 'Alex Lehmann', 'Roman Gackowski', 'Benjamin Dickinson', 'Mads Matthiesen', 'John Schultz', 'Simon Baker', 'Fernando Moro', 'Jay Chapman', 'Kasra Farahani']
    -['Jay Karas', 'Ladislas Chollat', 'Michael Mason', 'Chris Howe', 'Ofir Raul Graizer', 'Sacha Wolff', 'Sofia Coppola', 'Nagesh Kukunoor', 'Prakash Jha', 'Ravi Babu', 'Sandeep Chatterjee', 'Shivam Nair', 'Soumitra Ranade', 'Manmohan Desai']
    -['Manish Jha', 'Raja Menon', 'Hrishikesh Mukherjee', 'Sagar Sarhadi', 'Jon Rosenbaum', 'Priyadarshan', 'Ram Gopal Varma', 'Raj Kapoor', 'David Carson', 'David Dhawan', 'Tom Holland', 'Hrishikesh Mukherjee', 'Tanveer Khan', 'Indra Kumar', 'Lee Tamahori']
    -['Chandra Barot', 'Ajay Phansekar', 'Rajkumar Santoshi', 'Partho Ghosh', 'Hrishikesh Mukherjee', 'Martin Campbell', 'Rohit Shetty', 'David Mirkin', 'Prakash Mehra', 'Bruce Leddy', 'Shirish Kunder', 'Madhur Bhandarkar', 'Radhu Karmakar', 'Ahishor Solomon', 'David Dhawan', 'Tinnu Anand']
    -['Sai Paranjape', 'Hrishikesh Mukherjee', 'Gulzar', 'Remy Kohli', 'David Dhawan', 'Shekhar Kapur', 'David Dhawan', 'Prakash Mehra', 'Karan Lalit Butani', 'Abhishek Saxena', 'Basu Chatterjee', 'Raj Kapoor', 'Sanjay Dayma', 'John Milius']
    -['Amit Rai', 'Raman Kumar', 'Balu Mahendra', 'Raj Kapoor', 'Raj N. Sippy', 'Ram Gopal Varma', 'Basu Chatterjee', 'Tariq Khan', 'Shakti Samanta', 'Michael Apted', 'Roger Spottiswoode', 'Madhur Bhandarkar', 'Shyam Benegal', 'Sanjay Patel', 'Ashu Trikha']
    -['Kushal Srivastava', 'Chandra Prakash Dwivedi', 'John Fortenberry', 'Chris Bould', 'Chris Bould', 'Kevin Booth, David Johndrow', 'Paul M. Green', 'Julio Fernández Talamantes', 'Walter C. Miller', 'Walter C. Miller']
    -['Walter C. Miller', 'Paul Dugdale', 'Tommy Avallone', 'Noriyuki Abe', 'Ellen Brown', 'Matt Askem', 'Matt Askem', 'Jay Chapman', 'Rob Zombie', 'Barry Avrich', 'Gary Cohen, Ross Hockrow']
    -['Stan Lathan', 'Fabien Beziat, Hugues Nancy', 'Nils Tavernier', 'Alethea Jones', 'Guy Vasilovich', 'Rich Ragsdale', 'Dana Doron, Uriel Sinai', 'Hidetaka Inazuka', 'James Brown', 'Paul Schrader', 'Diego Luna']
    -['Brittany Andrews', 'Tim Blake Nelson', 'André Øvredal', 'Jay Baruchel', 'Rodrigo Van Der Put', 'Linda Mendoza', 'John Michael McDonagh', 'Theo Davies', 'Timothy Woodward Jr.', 'Benoît Jacquot', 'Fernando Frías De La Parra']
    -['John Hillcoat', 'Måns Mårlind, Björn Stein', 'Ludovic Bernard', 'Jason Moore', 'Yuki Yamato', 'Álvaro Brechner', 'Levan Tsikurishvili', 'Rakesh Mehta', 'Mat Whitecross']
    -['Eduardo Chauvet', 'Gonzalo Bendala', 'Stefan Aust, Dirk Laabs', 'Biyi Bandele', 'Andrew Wessels', 'Emir Kusturica', 'Chris Renaud', 'Odunlade Adekola', 'Jason Stone', 'Detlev Buck', 'Luis Prieto']
    -['Elisa Fuksas', 'Vic Armstrong', 'Anne Fontaine', 'Lee Toland Krieger', 'Noël Wells', 'Jay Chapman', 'Marc Francis, Max Pugh', 'Alik Sakharov', 'Tony Giglio']
    -['Akiyuki Shinbo, Nobuyuki Takeuchi', 'Ron Oliver', 'Don Michael Paul', 'Shojiro Nishimi, Guillaume Renard', 'J.D. Dillard', 'Anthony Russo, Joe Russo', 'Michael Petroni', 'Erik Nelson', 'Ritu Sarin, Tenzing Sonam', 'Pepe Bojórquez', 'Rhys Thomas']
    -['Jeff Baena', 'Noam Murro', 'Patrick Brice', 'Daniel Kontur', 'Jorge Michel Grau', 'Riki Lindhome, Jeremy Konner', 'Werner Herzog', 'David M. Rosenthal', 'Ross Boyask', 'Bruce Beresford', 'David Ayer']
    -['Satyajit Bhatkal', 'Louise Alston', 'Sunkanmi Adebayo', 'Kheiron', 'Susanne Bier', 'Irek Dobrowolski', 'Rodrigo Van Der Put', 'Josh Mendoza']
    -['Diego Kaplan', 'Ari Levinson', 'George Ford', 'George Ford', 'Omoni Oboli', 'Falz', 'Frank Rajah Arase', 'Omoni Oboli', 'Fernando Meirelles', 'Hasraf Dulull', 'Gilbert Chan', 'Rarecho', 'Steve Cheng']
    -['Sam Loh', 'Jason Lai', 'Marco Deufemia, Justin G. Dyck', 'Lydia Tenaglia', 'Thomas Astruc', 'Pablo Parés', 'Manny Rodriguez', 'David Grossman', 'Mario Cambi', 'Luc Vinciguerra', 'Luc Vinciguerra', 'Ahsan Rahim', 'Yorgos Lanthimos']
    -['Imtiaz Ali', 'Michael Barrett', 'Adam Nimoy', 'Elizabeth Wood', 'Kevin Smith', 'Rodrigo Reyes', 'Samit Kakkad', 'Kenny Young', 'Peter Orton', 'Emil Ben-Shimon', 'Kenny Young', 'Julia Hart']
    -['Warren P. Sonoda', 'Mark Lewis', 'Joel Gallen, Tig Notaro', 'Rob W. King', 'Ian MacAllister-McDonald', 'L. Frazier', 'Paul Reubens, Wayne Orr', 'Sebastian DiNatale', 'Prasobh Vijayan', 'Jon Rosenbaum', 'Ekachai Uekrongtham', 'Jay Surridge', 'Jayson Thiessen, Ishi Rudell', 'Steve Antin']
    -['Nuhash Humayun, Syed Ahmed Shawki, Rahat Rahman, Robiul Alam Robi, Golam Kibria Farooki, Mir Mukarram Hossain, Tanvir Ahsan, Mahmudul Islam, Abdullah Al Noor, Krishnendu Chattopadhyay, Syed Saleh Ahmed Sobhan', 'Tom Hooper', 'Brendon Marotta', 'Sriram Raghavan', 'Elaine Bogan, John Sanford', 'Michael Cuesta', 'David Cronenberg', 'Lone Scherfig', 'Thom Zimny', 'James Marsh', 'Gordon Chan', 'Vikram Gandhi']
    -['Morgan Spurlock', 'Sean Hanish', 'David Shisgall', 'Mark Williams', 'Karan Anshuman', 'Obi Emelonye', 'Farhan Akhtar', 'Zoya Akhtar', 'Farhan Akhtar', 'Farhan Akhtar', 'Mrighdeep Singh Lamba', 'Abhinay Deo', 'Tsutomu Mizushima']
    -['Fernando Ayllón', 'Reema Kagti', 'Brodje Wemboendja', 'Jadesola Osiberu', 'Vijay Lalwani', 'Farhan Akhtar', 'Zoya Akhtar', 'Shirley Frimpong-Manso', 'Abhishek Kapoor', 'Hiroshi Aoyama, Kazumi Fukushima, Jim Stenstrum', 'Reema Kagti', 'Phil Roman', 'Téo Frank', 'Zoya Akhtar']
    -['Sean Olson', 'Sigrid Andrea Bernardo', 'Matt Askem', 'Matt Askem', 'Guillermo de Oliveira', 'Elliot Hegarty', 'Manoj Beedha', 'Vikram Bhatt']
    -['Daniel Alfredson', 'Jody Lambert', 'Sridhar Rangayan', 'Ernie Barbarash', 'Agnidev Chatterjee', 'Todd Standing', 'Marc Levin', 'Manbhavan Singh', 'Pa. Ranjith', 'Ignacio López Escrivá', 'Rahat Kazmi', 'Nicholas Kharkongor']
    -['Varun Narvekar', 'Seth Henrikson', 'Devaki Singh, Luke Kenny', 'Benson Lee', 'Antonio Serrano', 'Chris Burkard', 'Sinan Akkuş', 'Matt Bell', 'Hardik Mehta']
    -['Ehtesham Uddin', 'Elite Zexer', 'Pedro Morelli', 'John Banas', 'Wim Bonte', 'Alfonso Cuarón', 'Bruce MacDonald, Gabriel Sabloff']
    -['Mike Nicoll', 'Michael Bay', 'Robert O. Peters', 'Bunmi Ajakaiye', 'Omoni Oboli', 'Biodun Stephen', 'M.J. Bassett', 'Ding-Lin Wang', 'Robert O. Peters', "Richard van't Riet", 'John Hoffman, Nanfu Wang', 'Marcus Raboy']
    -['Michael Winterbottom', 'Jean-Pierre Dardenne, Luc Dardenne', 'Gurinder Chadha', 'Gabriela Cowperthwaite', 'Raúl Campos, Jan Suter', 'Christopher Smith', 'Josh Greenbaum', 'Shonali Bose', 'Adam Alleca', 'Marcus Raboy', 'Craig Anderson', 'Michael G. Kehoe', 'Alex Lehmann', 'Frank Coraci', 'Sameh Abdulaziz']
    -['Lance Bangs', 'Hiroshi Katagiri', 'Ivan Sen', 'Anthony Caronna, Alexander Smith', 'Jeffrey C. Bell', 'Michelle Johnston', 'John Fortenberry', 'Jay Roach', 'Jay Roach', 'Jay Roach', 'Vijay Kumar Arora', 'Matt Shakman', 'Mikhail Red', 'Pankaj Batra']
    -['Craig Brewer', 'Serge Ou', 'Navaniat Singh', 'Gaurav Bavdankar', 'David Raynr', 'Gregory Hoblit', 'Jagdeep Sidhu', 'Malik Bendjelloul', 'Jamie M. Dagg', 'Tanawat Aiemjinda', 'Robert Rodriguez', 'Martin Scorsese']
    -['Brendan Malloy, Emmett Malloy', 'Mukesh Vohra', 'Syrine Boulanouar, Nekfeu', 'Tudor Giurgiu', 'Andrew Lau Wai-Keung', 'Cheang Pou Soi', 'Enrique García Meza', 'Katarina Launing', 'Johnnie To', 'Gabriel Clarke, Torquil Jones', 'Lawrence Cheng', 'Prakash Balwant Saini', 'Nam Ron', 'Johnnie To']
    -['Johnnie To', 'Baljit Singh Deo', 'Leung Lok Man, Luk Kim-ching', 'Guillermo del Toro', 'Jazz Boon', 'Prakash Satam', 'Andrew Lau Wai-Keung', 'Felix Chong', 'Dhanush', 'Gary Mak', 'Liu Jiang']
    -['Gabriele Muccino', 'Blake Harris, Chris Bouchard', 'Evan Spiridellis, Jeff Gill', 'Jasbir Bijendra Bhati', 'Tristan Ferland Milewski', 'Harjit Singh', 'Jon Carey, Adam Darke', 'Jennifer Lynch', 'Leopoldo Aguilar', 'Nana Ekvtimishvili, Simon Gross']
    -['Olivier Jean-Marie', 'Daniel Mann, Joseph Sargent', 'Ashish R. Shukla', 'Rohit Jugraj', 'Priyadarshan', 'Peter Spirer', 'Ali F. Mostafa', 'Myles Kane, Josh Koury', 'Robert McCullough Jr.', 'Shrihari Sathe', 'Ralph Macchio', 'Ricardo Maldonado']
    -['Vetrimaaran', 'Chad L. Scheifele', 'Linas Phillips', 'Jeff Margolis', 'Einar Gabbassov', 'Bauddhayan Mukherji', 'Mark Risley']
    -['Ishi Rudell, Jayson Thiessen', 'Susan Lambert, Stefan Moore', 'Tim Johnson', 'Robert Moresco', 'Aadish Keluskar', 'Joe Murray, Cosmo Segurson', 'Jesse Moss', 'Michael Fahey', 'Alejandro Montiel', 'Ian Cheney', 'Jesse Gustafson']
    -['John Schultz', 'Shin Won-ho', 'Shin Won-ho', 'Nancy Schwartzman', 'Darren Lynn Bousman', 'Ted Demme', 'Sujoy Ghosh', 'John Papola']
    -['John Asher', 'S.S. Rajamouli', 'S.S. Rajamouli', 'S.S. Rajamouli', 'S.S. Rajamouli', 'S.S. Rajamouli', 'S.S. Rajamouli', 'Osman Ali', 'Rolfe Kanefsky', 'Mae Czarina Cruz', 'Lance Bangs', 'Shannon Hartman', 'Christopher Nolen', 'Billy Corben', 'Joe DeMaio']
    -['Rob Silvestri', 'Mohamed Samy', 'Alex Burunova', 'Jesús Torres Torres', 'Matthias Hoene', 'Chris Nahon', 'Dante Lam', 'Ringo Lam', 'Alex Coletti', 'Mark Osborne', 'Christian De Vita', 'Abhishek Varman', 'Sabir Khan', 'Nikhil Nagesh Bhat']
    -['Xiaoxing Yi, Yoshitaka Takeuchi, Haoling Li', 'Raúl Campos, Jan Suter', 'Bryan Fogel', 'Fabrice Du Welz', 'Rohit Shetty', 'Johnnie To', 'Wong Jing', 'Mateo Gil']
    -['Paul Andrew Williams', 'Rémy Four, Julien War', 'Fernando Ayllón', 'Alejandro Fernández Almendras', 'Jota Linares', 'Will Lockhart, Cole D. Pruitt', 'Erwin van den Eshof', 'Lauren Miller Rogen']
    -['Fernando González Molina', 'Joseph Mbah', 'Roger Kumble', 'Wagner de Assis', 'David Mackenzie', 'Jacob Kornbluth', 'Robert Adetuyi', 'Marcus Raboy', 'White Trash Tyler', 'Van M. Pham', 'Shivam Nair', 'Tanuja Chandra', 'A.R. Murugadoss', 'Gaby Dellal', 'Chris Bell']
    -['John Barnard', 'Stan Lathan', 'Philip Yung', 'Sarah Adina Smith', 'Aaron Burns', 'Abdellatif Kechiche', 'Jay Karas', 'Christopher Louie', 'Tim Rouhana', 'Joe Berlinger', 'Ana Kokkinos', 'Toshiya Shinohara', 'Jordan Brady', 'Lars von Trier', 'Keiko Yagi']
    -['Cate Shortland', 'Adam Wingard', 'Mohd Khairul Azri Bin Md Noor', 'Daniela Goggi', 'Toby Haynes', 'Yeung Yat-Tak', 'Keith L. Smith', 'Todd Biermann', 'Patrick Graham', 'Mike Clattenburg', 'Han Qing', 'Ian Edelman']
    -['Randall Lobb, Robert McCallum', 'Rai Yuvraj Bains', 'Sunil Thakur', 'Muh Chen', 'Saurabh Sinha', 'Ari Folman', 'Bassam Kurdali', "Brian O'Malley", 'Peter Spirer', 'Marcus Raboy', 'Michael Seater', 'Steven Bognar, Julia Reichert', 'Ashwin Saravanan']
    -['Ashwin Saravanan', 'Ashwin Saravanan', 'Jun Lana', 'Ashwiny Iyer Tiwari', 'Atlee Kumar', 'Ravi Udyawar', 'R. Balki', 'Shree Narayan Singh', 'Salima Koroma', 'Woo Ming Jin', 'Shamyl Othman', 'Michael Mazzola', 'Martin Scorsese']
    -['Julia Knowles', 'Scott Marshall Smith', 'Nagesh Kukunoor', 'Dean Wright', 'Camille Shooshani', 'Lesli Linka Glatter', 'Vijay Kumar', 'Vishal Bhardwaj', 'Vikas Bahl, Nitesh Tiwari', 'Stacie Passon', 'Michael Thelin', 'Madhur Bhandarkar']
    -['Abhishek Kapoor', 'Khalid Mohamed', 'Luis Ara', 'Sanjay Leela Bhansali', 'Vishal Bhardwaj', 'Imtiaz Ali', 'Punit Malhotra', 'Shirish Kunder', 'Dibakar Banerjee', 'Prem Soni', 'Ashutosh Gowariker', 'Clarence Yiu-leung Fok', 'Prakash Jha', 'Rakeysh Omprakash Mehra', 'Prabhu Deva', 'Imtiaz Ali']
    -['Farah Khan', 'Mandeep Kumar', 'Anees Bazmee', 'Vishal Bhardwaj', 'Michael Drumm', 'Fabrizio Copano, Augusto Matte', 'Esteban Vidal', 'Esteban Vidal', 'Liu Jie', 'Ding Sheng', 'Justin Krook', 'Gervasio Iglesias, Alexis Morante', 'Will Gluck']
    -['Daniel Lindsay, T.J. Martin', 'Tommy Wirkola', 'Michael Carney', 'Manuel Martín Cuenca', 'Susan Johnson', 'Y. Joon Chung', 'Jon Rosenbaum']
    -['Mark Murphy', 'Tarsem Singh', 'Michael Tiddes', 'Kepa Sojo', 'Vikramaditya Motwane', 'Wong Jing', 'Chia-Liang Liu', 'Chia-Liang Liu', 'Johnnie To', 'Sze Yu Lau']
    -['Stephen Chow', 'Johnnie To', 'Li Pei-Chuan', 'Chia-Liang Liu', 'Anthony Chan', 'Siu-hung Chung, Wong Jing', 'Poj Arnon', 'Chia Tang', 'Alex Law', 'Chia-Liang Liu', 'Herman Yau', 'Cheh Chang', 'Johnnie To', 'Johnny To', 'Sze Yu Lau', 'Zach Braff']
    -['Rajiv Chilaka, Binayak Das', 'Cho Li, Chen Hung-yi, Weica Wang, Liu Bang-yao, Lin Guan-fu, Shen Chi, YC Tom Lee', 'Diego Pignataro', 'Kyle Rideout', 'Gajendra Ahire, Viju Mane, Girish Mohite, Ravi Jadhav', 'Rucha Humnabadkar', 'Scott Cooper', 'Matt Kugelman', 'Ashutosh Gowariker', 'Matthew Salleh', 'Jay Chapman', 'Jay Chapman']
    -['Michael Dowse', 'Nathaniel Warsh', 'Alejandro Agresti', 'Anthony Wonke', 'Ashim Ahluwalia', 'Louis C.K.', 'Robert Nixon, Fisher Stevens', 'Manu Ashokan', 'James Lee']
    -['Peter Hutchings', 'Jay Karas', 'Anita Udeep', 'Vlad Yudin', 'Alberto Arnaut Estrada', 'Barak Goodman', 'Max McGill', 'David Fairhead', 'Victor Zarcoff', 'Jean-Claude La Marre', 'Jorge Hernandez Aldana', 'Michael Tiddes', 'Michael Drumm', 'Troy Miller']
    -['Jay Karas', 'Jay Chapman', 'Majid Majidi', 'Eduardo Chauvet', 'Mike Newell', 'Jake Szymanski', 'Floyd Russ', 'Susan Glatzer', 'Will Canon', 'Barney Clay', 'Ernie Barbarash', 'Rajkumar Hirani', 'Khaled El Halafawy']
    -['Todor Chapkanov', 'Louis Leterrier', 'Prawal Raman', 'Sriram Raghavan', 'Rajesh Mapuskar', 'Mike Newell', 'Alexandre Aja', 'Quentin Tarantino', 'Lana Wachowski, Lilly Wachowski', 'Kazuaki Kiriya', 'Phanindra Narsetti', 'Bharat Nalluri', 'David Fincher', 'John G. Avildsen']
    -['Sylvester Stallone', 'Sylvester Stallone', 'Sylvester Stallone', 'John G. Avildsen', 'Rob Reiner', 'Chris Stokes', 'Nancy Meyers', 'Clint Eastwood', 'Beeban Kidron', 'Bejoy Nambiar', 'Paul Raschid', 'Mel Smith', 'Jesse Handsher, Olivier Roland']
    -['Wong Jing', 'Bradley Parker', 'Wong Jing', 'Gregory Caruso', 'Corey Yuen', 'Vishnu Govindhan', 'Andrew Lau Wai-Keung, Alan Mak', 'Pablo Giorgelli', 'Jijo Pancode', 'Andrés Couturier', 'Suresh Pillai', 'B.N. Shajeer Sha', 'Hua Shan', 'Alessandro Angulo', 'Pang Ho-cheung', 'Amaan Khan']
    -["Pablo D'Alo Abba", 'Binu Ulahhannan', 'Anil Thomas', 'Sabu Varghese', 'Matt Askem', 'Charlie Lightening', 'Charlie Lightening', 'Matt Askem', 'Kiran Narayanan', 'Kundan Shah', 'Richard Correll', 'Amir Mohiuddin', 'Zakariya', 'Alistair Legrand']
    -['Steven Soderbergh', 'John Duigan', 'Aditya Kripalani', 'Maria Burton', 'Charlie Vaughn', 'Avinash Das', 'Paul Serafini', 'April Mullen', 'Lilly Wachowski, Lana Wachowski, Tom Tykwer', 'Ben Steele']
    -['John Butler', 'Ali Scher', 'Maz Jobrani', 'Isaac Rentz', 'Clay Glen', 'Christopher Murray', 'Kevin Ford, Smriti Keshari, Eric Schlosser']
    -['David Briggs', 'Neil Rawles', 'Claude Lelouch', 'J.F. Musial, Josh Vietze', 'John Smithson', 'Daniel Kontur', 'Neil Armfield', 'Cal Saville', 'Christopher Martin']
    -['Tom Whitter', 'Peter Farrelly, Will Graham, Steve Carr, Griffin Dunne, Steve Brill, James Duffy, Jonathan van Tulleken, Elizabeth Banks, Patrik Forsberg, Brett Ratner, Rusty Cundieff, James Gunn', 'Brian M. Conley, Nathan Ives', 'Lena Khan', 'David Wnendt', 'Rajiv Menon']
    -['Justin Webster', 'Suman Mukhopadhyay', 'Mike Flanagan', 'Karthik Subbaraj', 'Brian Smrz', 'Kim A. Snyder', 'Ester Gould, Reijer Zwaan', 'Gerardo Olivares', 'Joe Swanberg', 'Maria Pulera', 'Werner Herzog', 'Marja Lewis Ryan', 'Ryan Koo', 'Hatem Khraiche']
    -['Derek Peck', 'Ryan Polito', 'Jennifer Morrison', 'Mitzi Vanessa Arreola, Amir Galvan Cervera', 'Raúl Campos, Jan Suter', 'Nicolas Pesce', 'Jeremiah Jones', 'Dave Patten', 'Prabhuraj', 'Karthik Subbaraj', 'Jean-Simon Chartier']
    -['Thomas Meadmore', 'Brie Larson', 'Katherine Fairfax Wright', 'Hèctor Hernández Vicens', 'Cem Yılmaz', 'Ömer Faruk Sorak', 'Sermiyan Midyat', 'Yılmaz Erdoğan', 'Kıvanç Baruönü', 'Ali Taner Baltacı', 'Bedran Güzel', 'Holger Tappe']
    -['Yılmaz Erdoğan', 'Cem Yılmaz', 'Louis C.K.', 'Herman Yau', 'Marcus Raboy', 'C.J. Wallis', 'Çagan Irmak', 'Amit Roy']
    -['Teddy Lussi-Modeste', 'Daniel Lee', 'Fernando Ayllón', 'Rocky Soraya, Anggy Umbara', 'Kader Aoun', 'Bille Woodruff', 'Abhay Chopra', 'Lee Chang-dong', 'Kranti Kanade', 'Dar Gai', 'Ricky Gervais', 'Jon Greenhalgh', 'Christopher S. Rech, Brandon Kimber', 'Kitty Green']
    -['Spike Lee', 'Evan Katz', 'Andrea Arnold', 'Dawn Porter', 'Ben Shelton', 'Curro Velázquez', 'Laura Brownson', 'Robert Smigel']
    -['Khaled Youssef', 'Wael Ehsan', 'Joachim Rønning, Espen Sandberg', 'Fernando Ayllón', 'Yılmaz Erdoğan', 'Sathyan Anthikad', 'Brian Oakes', 'Dominic Sena', 'Wayne Blair', 'Max Amini', 'Dimitri Logothetis', 'Simon Stone']
    -['Ahmad El-Badri', 'Yam Laranas', 'Ari Sandel', 'Ahmad Samir Farag', 'Mohamed Samy', 'Chris Sivertson', 'Amr Arafa', 'Quentin Tarantino', 'Robert Luketic', 'Jason Sussberg, David Alvarado', 'Célia Catunda, Kiko Mistrorigo, Rodrigo Eba', 'Sang-ho Yeon', 'Gauri Shinde', 'Oliver Schmitz', 'Felix Herngren, Måns Herngren', 'Marcus Raboy']
    -['Camilla Nielsson', 'Sabal Singh Shekawat', 'Adam Del Giudice', 'Andy Fickman', 'Robert Tate', 'Prakash Satam', 'Kasia Uscinska', 'Susannah Ward', 'Sam Taplin', 'Vicky Matthews, Gareth Sacala', 'Louise Wardle', 'Shalini Kantayya']
    -['Alastair Fothergill', 'Dennis Scholl, Kareem Tabsch', 'Jill Bauer, Ronna Gradus, Rashida Jones', 'Fernando Coimbra', 'Adam Leon', 'Bille August', 'Fab Five Freddie', 'Rebecca Addelman', 'Olivia Milch', 'Mark Raso']
    -['David Sington, Heather Walsh', 'Dylan C. Brown', 'Chris Stokes', 'Shelly Chopra Dhar', 'Shanjey Kumar Perumal', 'Leslie Small', 'Andrew Niccol', 'Jarrad Paul, Andrew Mogel', 'Michael Doneger', 'Sandra Restrepo', 'Ken Loach', 'Sarthak Dasgupta']
    -['Sameh Abdulaziz', 'Jennifer Kaytin Robinson', 'Ken Burns, Christopher Loren Ewers, Erik Ewers', 'Renato De Maria', 'Pedro Coutinho', 'Wong Jing, Jason Kwan', 'Barak Goodman', 'Barak Goodman', 'Hani Hamdi', 'Khaled El Halafawy', 'Ismail Farouk', 'Moataz El Tony', 'Ossama Abu El Atta, Tarek Al Eryan']
    -['Hadi El Bagoury', 'Simon Verhoeven', 'Ron Oliver', 'Jay Chapman', 'Alan Rickman', 'Hasan Karacadağ', 'Dylan Haegens, Bas van Teylingen', 'Ulises Valencia', 'Beyoncé Knowles-Carter', "Bill D'Elia", 'Jon Lucas, Scott Moore', 'Richard Curtis']
    -['Tom Shadyac', 'Bill Oliver', 'Jennifer Beamish, Toby Trackman', 'Paul Weitz', 'Gabe Klinger', 'David Gordon Green', 'Nagesh Kukunoor', 'Suparn Verma', 'Vlad Yudin', 'Sudhir Mishra', 'Sujoy Ghosh', 'Anant Balani', 'Soukarya Ghosal', 'Leena Yadav']
    -['Amitabha Singh', 'Carly Stone', "Liam O'Donnell", 'Bruce Gowers', 'Ron Oliver', 'Enrico Bisi', 'Michael Lennox', 'Detlev Buck', 'Detlev Buck', 'Detlev Buck']
    -['Andrea Molaioli', 'Kemi Adetiba', 'Aaron Nee, Adam Nee', 'Felix Van Groeningen, Felix van Groeningen', 'Chris Bell, Josh Alexander, Greg Young', 'Werner Herzog', 'Ken Barbet', 'Dallas Jackson', 'Sam Taylor-Johnson', 'Marie Madinier', 'Miguel Ángel Lamata', 'Steven Brill', 'Antonio Chavarrías', 'Tiller Russell', 'Gabriel Julien-Laferrière', 'Yeo Siew Hua']
    -['Jota Linares', 'Joshua Marston', 'Eleonore Pourriat', "Anthony D'Souza", 'Zoe Lister-Jones', 'Mike Wiluan', 'Hasan Karacadağ', 'Hasan Karacadağ', 'Ayush Raina', 'Chris Nelson']
    -['Peter Webber', 'Antonio Serrano', 'Raphael Erichsen', 'Lee Kyoungmi, Yim Pilsung, Jeon Go-woon, Kim Jong-kwan', 'Leslie Small', 'Michael Kennedy', 'Fernando Ayllón', 'John R. Leonetti', 'Peter Orton', 'Grant S. Johnson, Ippsie Jones', 'Shravan Kumar', 'Julien Christian Lutz', 'Nick Davis']
    -['Jason Winer', 'Gregory Hoblit', 'Peter Segal', 'Huang Jianming', 'Laura VanZee Taylor', 'Gerry Hoban', 'Tianyu Zhao', 'Richard LaGravenese', 'Mark Palansky', 'Shazia Ali Khan', 'Guy Ritchie']
    -['Robert Rodriguez', 'Robert Rodriguez', 'Stacy Title', 'Bumpy', 'Manish Jha', 'Erik White', 'Ben Brewer, Alex Brewer', 'Victoria Bromley', 'Philip G. Atwell', 'Padmakumar Narasimhamurthy', 'Stephen Gyllenhaal', 'Diego Lerman', 'Don Bluth']
    -['Phil Nibbelink, Simon Wells', 'Larry Latham', 'Larry Latham', 'Simon Wells', 'Phil Weinstein', 'Phil Weinstein', 'Rajkumar Santoshi', 'Kaspar Astrup Schröder', 'Priyadarshan', 'Gregory Hoblit', 'Gary David Goldberg', 'Raj Amit Kumar', 'Kundan Shah']
    -['Keith Malloy', 'Nanette Burstein', 'Jocelyn Moorhouse', 'Luca Vullo', 'Ryan Polito', 'Kundan Shah', 'Jared Cohn', 'Farah Khan', 'Tathagata Banerjee', 'Ananda Krishnan', 'Farah Khan', 'Amol Palekar']
    -['Aziz Mirza', 'Kookie V. Gulati', 'Atanu Mukherjee', 'Nagraj Manjule', 'Steven Spielberg', 'Billy Ray', 'Esteban Sapir', 'Saul Dibb', 'Stephen Amezdroz', 'Benedict Andrews', 'Sushrut Jain', 'Gayane Petrosyan']
    -['Shivendra Singh Dungarpur', 'Alexandre Reinecke', 'Philipp Eichholtz', 'Jamal Hill', 'Daniel Gordon', 'K. Ramanlal', 'Maris Curran', 'John Edginton', 'Avinash Arun', 'Ed Gass-Donnelly', 'Jason Spingarn-Koff', 'Takuya Igarashi']
    -['A. Salaam', 'Jason Cohen', 'Eduardo Casanova', 'Keith Fulton, Louis Pepe', 'Rudradeep Bhattacharjee', 'Daniel Burman', 'Kike Maíllo', 'G.J. Echternkamp', 'G.J. Echternkamp', 'Zatella Beatty', 'Vlad Yudin']
    -['Mario Van Peebles, Ralph Hemecker, Gwyneth Horder-Payton, Milan Cheylov, Dean White, Michael Waxman, Bryan Spicer', 'Danny Cannon']
    -[]
    -[]
    -['Hayato Date', 'Michael Cumming']
    -[]
    -['Eli Roth']
    -[]
    -[]
    -[]
    -[]
    -['Go Koga']
    -['Everardo Gout']
    -['Bhavik Thakore', 'Phil Sgriccia', 'Rob Seidenglanz']
    -['Jesse Warn', 'Rob Seidenglanz', 'Glen Winter', 'Carlos Sedes', 'James Bamford']
    -['Jay Chandrasekhar', 'Philippa Lowthorpe']
    -['Ian Barber', 'Gordon Anderson']
    -[]
    -['Vijay Roche']
    -[]
    -[]
    -['Iginio Straffi']
    -['Stefan Brogren', 'Tensai Okamura']
    -['Peter McDonnell']
    -['Jerry Seinfeld']
    -[]
    -[]
    -['Tony Collingwood']
    -['Yasuhiro Irie']
    -[]
    -[]
    -['Dan Forrer']
    -[]
    -['James Hawes']
    -[]
    -['Jung-ah Im, Seung-uk Jo', 'Andy Devonshire']
    -['Thomas Astruc']
    -['Vikramaditya Motwane, Anurag Kashyap']
    -['Jung-ah Im']
    -[]
    -['Onur Ünlü']
    -[]
    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    - -
    - {% endraw %} -
    - - diff --git a/docs/widgets.html b/docs/widgets.html deleted file mode 100644 index f18b439..0000000 --- a/docs/widgets.html +++ /dev/null @@ -1,481 +0,0 @@ ---- - -title: Images - - -keywords: fastai -sidebar: home_sidebar - -summary: "Image widgets for jupyter noteook" -description: "Image widgets for jupyter noteook" -nb_path: "nbs/51_widgets.ipynb" ---- - - -
    - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Imports

    -
    -
    -
    - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Data url for img tag

    Use data url in <img src='data:...'>

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    image_to_base64[source]

    image_to_base64(img:PIL.Image)

    -
    -

    Transform PIL Image to base64 for API -Return:

    - -
    - base64 encoded image bytes
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    data_url[source]

    data_url(img:PIL.Image)

    -
    -

    Return:

    - -
    - data url string,
    -    can be used as the src value of <img>
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Preview images in jupyter notebook

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    image_dom[source]

    image_dom(img:PIL.Image, **kwargs)

    -
    -

    Create tag with src='data:...' - with PIL.Image object -return forgebox.html.DOM

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    with_title_dom[source]

    with_title_dom(img:PIL.Image, title:str, col:int)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    view_images[source]

    view_images(*images, num_per_row:int=4, titles:List[T]=None)

    -
    -

    Create

    wraping up images -view_images( - img1, img2, img3, - img4, img5, img6, - img7)()

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Subplot

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class Subplots[source]

    Subplots(total:int, ncol:int=3, figsize=None)

    -
    -

    Simplifying plt sublots -sub = Subplots(18)

    - -
    @sub.single
    -def plotting(ax, data):
    -    ax.plot(data)
    -
    -for data in data_list:
    -    sub(data)
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Test on image preview

    -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    import os
    -
    - -
    -
    -
    - -
    - {% endraw %} - -
    -
    -

    Original image

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    HOME = os.environ['HOME']
    -img = Image.open(f"{HOME}/Pictures/img02.jpg").resize((200,50))
    -img
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    Data url of the image

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    data_url(img)[:100]
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    'data:image/jpg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHB'
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    Visualize single image

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    image_dom(img)()
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    Visualize serveral images

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    view_images(img, img, img, img, img, img, titles=list(f"lake:{i}" for i in range(6)))()
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    lake:0
    lake:1
    lake:2
    lake:3
    lake:4
    lake:5
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    Contains more images in a row

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    view_images(
    -    img, img, img, img, img, img,
    -    num_per_row=6)()
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    - - diff --git a/docs/wild_tree_and_loss.html b/docs/wild_tree_and_loss.html deleted file mode 100644 index 7363cc9..0000000 --- a/docs/wild_tree_and_loss.html +++ /dev/null @@ -1,946 +0,0 @@ ---- - -title: Wild Tree and loss - - -keywords: fastai -sidebar: home_sidebar - -summary: "A tree loss for classifiying categories as a tree structure" -description: "A tree loss for classifiying categories as a tree structure" -nb_path: "nbs/40_wild_tree_and_loss.ipynb" ---- - - -
    - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Sample data

    -
    -
    -
    -
    -
    -

    We down load the data from oncotree here, save as json file

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    import os
    -import json
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    with open(Path(os.environ['HOME'])/"Downloads"/"oncotree.json","r") as f:
    -    oncotree = json.load(f)
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    oncotree['TISSUE'].keys()
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    dict_keys(['code', 'color', 'name', 'mainType', 'externalReferences', 'tissue', 'children', 'parent', 'history', 'level', 'revocations', 'precursors'])
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    Wildtree

    -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    cache[source]

    cache(f:Callable)

    -
    -

    cache for class property, use as decorator

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class WildNode[source]

    WildNode(name)

    -
    -

    A node in graph, with uncertain edge possibilities

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class WildEdge[source]

    WildEdge(parent:WildNode, kid:WildNode)

    -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    class WildTree[source]

    WildTree()

    -
    -

    A tree that will analyze a tree structure - from (parent-kid) pairs data - use tree.create_new_edge('parent','kid') to - add a new edge

    -

    The tree doesn't have to be a very clear structure, - 2 nodes can have both parent-kid and siblings relationship - the tree will find the shortest path anyway

    -

    Important

    After added all the edges**, use tree.root_map for - finding the tree root.

    -

    tree('name1','name2') to get a dataframe on travel path

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - -
    -
    -

    Test wildtree

    -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    def parse_node(node: WildNode, callback: Callable) -> None:
    -    parent = node['name']
    -    if 'children' in node:
    -        for child_name,child_node in node['children'].items():
    -            # this is the onlything you have to do to fill a 
    -            # wild tree data, create new edge for 
    -            # every parent/kid string pairs
    -            callback(parent, child_node['name'])
    -            parse_node(child_node, callback=callback)
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    tree = WildTree()
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    parse_node(oncotree['TISSUE'], callback=tree.create_new_edge)
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    tree.root_map()
    -
    - -
    -
    -
    - -
    - {% endraw %} - -
    -
    -

    WildTree found the root node automatically

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    tree.root
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    Tissue
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    print('\t'.join(list(tree.nodes.keys())[:100]))
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    Tissue	Ovary/Fallopian Tube	Ovarian Cancer, Other	Ovarian Choriocarcinoma, NOS	High-Grade Neuroendocrine Carcinoma of the Ovary	High-Grade Serous Fallopian Tube Cancer	Ovarian Epithelial Tumor	Endometrioid Borderlin Ovarian Tumor	Serous Ovarian Cancer	High-Grade Serous Ovarian Cancer	Low-Grade Serous Ovarian Cancer	Brenner Tumor	Brenner Tumor, Benign	Brenner Tumor, Borderline	Brenner Tumor, Malignant	Clear Cell Borderline Ovarian Tumor	Ovarian Seromucinous Carcinoma	Ovarian Seromucinous Adenoma	Endometrioid Ovarian Cancer	Serous Borderline Ovarian Tumor	Mucinous Ovarian Cancer	Serous Borderline Ovarian Tumor, Micropapillary	Mixed Ovarian Carcinoma	Mucinous Borderline Ovarian Tumor	Clear Cell Ovarian Cancer	Small Cell Carcinoma of the Ovary	Ovarian Seromucinous Borderline Tumor	Ovarian Carcinosarcoma/Malignant Mixed Mesodermal Tumor	Ovarian Germ Cell Tumor	Immature Teratoma	Polyembryoma	Mixed Germ Cell Tumor	Mature Teratoma	Dysgerminoma	Embryonal Carcinoma	Yolk Sac Tumor	Sex Cord Stromal Tumor	Sertoli-Leydig Cell Tumor	Steroid Cell Tumor, NOS	Granulosa Cell Tumor	Gonadoblastoma	Fibrothecoma	Lymphoid	Lymphoid Neoplasm	Posttransplant Lymphoproliferative Disorders	Classical Hodgkin Lymphoma PTLD	Polymorphic PTLD	Florid Follicular Hyperplasia PTLD	Monomorphic PTLD (B- and T-/NK-cell types)	Plasmacytic Hyperplasia PTLD	Infectious Mononucleosis PTLD	B-Lymphoblastic Leukemia/Lymphoma	B-Lymphoblastic Leukemia/Lymphoma with Recurrent Genetic Abnormalities	B-Lymphoblastic Leukemia/Lymphoma, BCR-ABL1 Like	B-Lymphoblastic Leukemia/Lymphoma with t(v;11q23.3);KMT2A Rearranged	B-Lymphoblastic Leukemia/Lymphoma with t(1;19)(q23;p13.3);TCF3-PBX1	B-Lymphoblastic Leukemia/Lymphoma with t(5;14)(q31.1;q32.3) IL3-IGH	B-Lymphoblastic Leukemia/Lymphoma with iAMP21	B-Lymphoblastic Leukemia/Lymphoma with Hyperdiploidy	B-Lymphoblastic Leukemia/Lymphoma with Hypodiploidy	B-Lymphoblastic Leukemia/Lymphoma with t(9;22)(q34.1;q11.2);BCR-ABL1	B-Lymphoblastic Leukemia/Lymphoma with t(12;21)(p13.2;q22.1); ETV6-RUNX1	B-Lymphoblastic Leukemia/Lymphoma, NOS	Non-Hodgkin Lymphoma	Mature B-Cell Neoplasms	Solitary Plasmacytoma of Bone	Follicular Lymphoma	In Situ Follicular Neoplasia	Duodenal-Type Follicular Lymphoma	Monoclonal B-Cell Lymphocytosis	Lymphoplasmacytic Lymphoma	Waldenstrom Macroglobulinemia	Burkitt Lymphoma	Primary Cutaneous DLBCL, Leg Type	EBV Positive Mucocutaneous Ulcer	DLBCL Associated with Chronic Inflammation	B-Cell Prolymphocytic Leukemia	Primary DLBCL of the central nervous system	B-Cell Lymphoma, Unclassifiable, with Features Intermediate between DLBCL and Classical Hodgkin lymphoma	Alpha Heavy-Chain Disease	Chronic Lymphocytic Leukemia/Small Lymphocytic Lymphoma	Mu Heavy-Chain Disease	Primary Cutaneous Follicle Center Lymphoma	Lymphomatoid Granulomatosis	High-Grade B-Cell Lymphoma, NOS	Monoclonal Gammopathy of Undetermined Significance	IgG	IgA	IgM	Burkitt-Like Lymphoma with 11q Aberration	HHV8 Positive DLBCL, NOS	Primary Mediastinal (Thymic) Large B-Cell Lymphoma	Plasmablastic Lymphoma	Gamma Heavy-Chain Disease	EBV Positive DLBCL, NOS	Large B-Cell Lymphoma with IRF4 Rearrangement	Extraosseous Plasmacytoma	Pediatric-Type Follicular Lymphoma	Hairy Cell Leukemia	High-Grade B-Cell Lymphoma, with MYC and BCL2 and/or BCL6 Rearrangements
    -
    -
    -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    tree('Chromophobe Renal Cell Carcinoma','Pleomorphic Adenoma')
    -
    - -
    -
    -
    - -
    -
    - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    namedirectionfreqto_root
    0Chromophobe Renal Cell Carcinomanone14
    1Renal Non-Clear Cell Carcinomaup13
    2Renal Cell Carcinomaup12
    3Kidneyup11
    4Tissueup10
    5Head and Neckdown11
    6Salivary Carcinomadown12
    7Pleomorphic Adenomadown13
    -
    -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    print(tree['Chromophobe Renal Cell Carcinoma'].detail)
    -
    - -
    -
    -
    - -
    -
    - -
    - -
    -
    <name:Chromophobe Renal Cell Carcinoma,level:4>
    -	parents:{'Renal Non-Clear Cell Carcinoma': 1}
    -	kids:{}
    -
    -
    -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    Integrate to binary cross entropy

    This part will create loss function with weights (according to tree), nhot encoder to translate string of a branch

    - -
    -
    -
    - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    calc_weight[source]

    calc_weight(x:array)

    -
    -

    Calculate the weight for BCELoss, - where the nodes closer to root will cause bigger loss - when it's wronged confidently

    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    -
    - -
    - - -
    -

    loss_package[source]

    loss_package(tree:WildTree)

    -
    -

    Create an entire package of things, -Input:

    -
      -
    • tree: WildTree -Output:
    • -
    • dictionary keys:
        -
      • weight
      • -
      • bce_loss: a pytorch nn module
      • -
      • encoder: Callable, a function translate name to nhot encoding
      • -
      • name_list: a list of entity names
      • -
      • to_root_list: an numpy array describe the

        travel distance to root

      • -
      -
    • -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    package = loss_package(tree)
    -
    - -
    -
    -
    - -
    - {% endraw %} - -
    -
    -

    Encoder function

    -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    from matplotlib import pyplot as plt
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    encoder = package['encoder']
    -
    - -
    -
    -
    - -
    - {% endraw %} - - {% raw %} - -
    -
    - -
    -
    -
    encoder('Renal Non-Clear Cell Carcinoma')[:200]
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    array([1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    -       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.,
    -       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    -       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    -       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    -       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    -       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    -       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    -       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0.,
    -       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    -       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    -       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    Visualize a port of nhot encoding

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    plt.imshow(encoder('Renal Non-Clear Cell Carcinoma')[None,:200].repeat(20,axis=0))
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    <matplotlib.image.AxesImage at 0x11c4f0710>
    -
    - -
    - -
    - - - -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    A list of int suggest the travel distance to root of all the categories

    -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    package['to_root_list']
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    array([0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    -       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    -       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    -       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    -       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    -       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    -       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    -       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    -       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    -       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    -       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    -       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    -       3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
    -       4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
    -       4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
    -       4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
    -       4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
    -       4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5,
    -       5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
    -       5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
    -       5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
    -       5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
    -       5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
    -       5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
    -       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6])
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    Loss function

    -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    bce_loss = package["bce_loss"]
    -type(bce_loss)
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    torch.nn.modules.loss.BCELoss
    -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    -
    -

    The loss function as weights according to the structure

    - -
    -
    -
    - {% raw %} - -
    -
    - -
    -
    -
    plt.imshow(bce_loss.weight.numpy()[None,].repeat(200,axis=0))
    -
    - -
    -
    -
    - -
    -
    - -
    - - - -
    -
    <matplotlib.image.AxesImage at 0x11d78b0d0>
    -
    - -
    - -
    - - - -
    - -
    - -
    - -
    -
    - -
    - {% endraw %} - -
    - - diff --git a/forgebox/__init__.py b/forgebox/__init__.py index b4ed79e..5becc17 100644 --- a/forgebox/__init__.py +++ b/forgebox/__init__.py @@ -1 +1 @@ -__version__ = "0.4.20" +__version__ = "1.0.0" diff --git a/forgebox/_nbdev.py b/forgebox/_nbdev.py deleted file mode 100644 index 6d0c233..0000000 --- a/forgebox/_nbdev.py +++ /dev/null @@ -1,199 +0,0 @@ -# AUTOGENERATED BY NBDEV! DO NOT EDIT! - -__all__ = ["index", "modules", "custom_doc_links", "git_url"] - -index = {"list_vc": "01_pandas_extra.ipynb", - "col_list_vc": "01_pandas_extra.ipynb", - "pd.DataFrame.vc": "01_pandas_extra.ipynb", - "pd.Series.list_vc": "01_pandas_extra.ipynb", - "pd.DataFrame.list_vc": "01_pandas_extra.ipynb", - "default_rename_rule": "01_pandas_extra.ipynb", - "rename_by_rule": "01_pandas_extra.ipynb", - "pd.DataFrame.rename_by_rule": "01_pandas_extra.ipynb", - "column_order": "01_pandas_extra.ipynb", - "pd.DataFrame.column_order": "01_pandas_extra.ipynb", - "__all__": "02_imports.ipynb", - "Path.ls": "02_imports.ipynb", - "Async": "03_async.ipynb", - "PandasDisplay": "03_df.ipynb", - "DOM": "04_html.ipynb", - "image_to_base64": "04_html.ipynb", - "data_url": "04_html.ipynb", - "img_dom": "04_html.ipynb", - "deeper": "04_html.ipynb", - "list_group": "04_html.ipynb", - "col_sm": "04_html.ipynb", - "list_group_kv": "04_html.ipynb", - "JS": "04_html.ipynb", - "JS_file": "04_html.ipynb", - "display_df": "05_inter_widgets.ipynb", - "search_box": "05_inter_widgets.ipynb", - "paginate": "05_inter_widgets.ipynb", - "make_hboxes": "05_inter_widgets.ipynb", - "SingleButton": "05_inter_widgets.ipynb", - "Labeler": "05_inter_widgets.ipynb", - "EditableList": "05_inter_widgets.ipynb", - "EditableDict": "05_inter_widgets.ipynb", - "total_width": "05_inter_widgets.ipynb", - "LivingStep": "05_inter_widgets.ipynb", - "StepByStep": "05_inter_widgets.ipynb", - "Flatten": "06_flatten.ipynb", - "l2norm": "06_spacy.ipynb", - "normal": "06_spacy.ipynb", - "distance": "06_spacy.ipynb", - "make_map": "06_spacy.ipynb", - "make_span": "06_spacy.ipynb", - "make_div": "06_spacy.ipynb", - "doc2div": "06_spacy.ipynb", - "compare_sentences": "06_spacy.ipynb", - "highlight": "06_spacy.ipynb", - "FreeMap": "07_freemap.ipynb", - "VipaClass": "09_multiprocess.ipynb", - "SingleFileLiner": "09_multiprocess.ipynb", - "DataFrameRowling": "09_multiprocess.ipynb", - "Stuff": "10_loop.ipynb", - "method4all": "10_loop.ipynb", - "StorageCore": "10_loop.ipynb", - "Loop": "10_loop.ipynb", - "ProgressBar": "10_loop.ipynb", - "error_tolerate": "10_loop.ipynb", - "Tolerate": "10_loop.ipynb", - "LambdaCall": "10_loop.ipynb", - "Event": "10_loop.ipynb", - "chunkify": "10_loop.ipynb", - "NewFileScanner": "11_etl.ipynb", - "get_static": "30_traceable_edit_in_flask.ipynb", - "open_static": "12_static_file.ipynb", - "create_event": "15_loopstack.ipynb", - "events": "15_loopstack.ipynb", - "LoopStack": "15_loopstack.ipynb", - "MetricTab": "15_loopstack.ipynb", - "train_callbacks": "15_loopstack.ipynb", - "eval_callbacks": "15_loopstack.ipynb", - "to_tensor": "15_loopstack.ipynb", - "simple_forward": "15_loopstack.ipynb", - "single_device": "15_loopstack.ipynb", - "TrainLoop": "15_loopstack.ipynb", - "EvalLoop": "15_loopstack.ipynb", - "find_stuff": "15_loopstack.ipynb", - "share_stuff": "15_loopstack.ipynb", - "Config": "20_config.ipynb", - "first": "20_config.ipynb", - "getall": "20_config.ipynb", - "now": "21_minimum.ipynb", - "Link": "21_minimum.ipynb", - "edit_js": "30_traceable_edit_in_flask.ipynb", - "DefaultTemp": "30_traceable_edit_in_flask.ipynb", - "Editable": "30_traceable_edit_in_flask.ipynb", - "pct_to_float": "31_df_filter.ipynb", - "ensure_pct": "31_df_filter.ipynb", - "detect_number_column": "31_df_filter.ipynb", - "DataFilter": "31_df_filter.ipynb", - "LayerTorch": "31_df_filter.ipynb", - "RecursiveFilterCore": "31_df_filter.ipynb", - "RecursiveFilter": "31_df_filter.ipynb", - "get_files": "33_files.ipynb", - "file_detail": "33_files.ipynb", - "cache": "40_wild_tree_and_loss.ipynb", - "WildNode": "40_wild_tree_and_loss.ipynb", - "WildEdge": "40_wild_tree_and_loss.ipynb", - "WildTree": "40_wild_tree_and_loss.ipynb", - "calc_weight": "40_wild_tree_and_loss.ipynb", - "loss_package": "40_wild_tree_and_loss.ipynb", - "image_dom": "51_image_widgets.ipynb", - "with_title_dom": "51_image_widgets.ipynb", - "view_images": "51_image_widgets.ipynb", - "Subplots": "51_image_widgets.ipynb", - "C2I": "53_category.ipynb", - "Category": "53_category.ipynb", - "TreeCategory": "53_category.ipynb", - "CosineSearch": "55_cosine_search.ipynb", - "CosineSearchWithCategory": "55_cosine_search.ipynb", - "unfreeze": "61_thunder_callbacks.ipynb", - "freeze": "61_thunder_callbacks.ipynb", - "DataFrameMetricsCallback": "61_thunder_callbacks.ipynb", - "UnfreezeScheduler": "61_thunder_callbacks.ipynb", - "nn.Module.unfreeze": "61_thunder_callbacks.ipynb", - "nn.Module.freeze": "61_thunder_callbacks.ipynb", - "convert_iob2_file_to_iobes": "70_hf_transformer_data.ipynb", - "conbine_iobes_file": "70_hf_transformer_data.ipynb", - "IOBES": "70_hf_transformer_data.ipynb", - "ner_model_from": "72_pl_training.ipynb", - "ner_tokenizer_from": "72_pl_training.ipynb", - "NERDataModule": "72_pl_training.ipynb", - "NERModule": "72_pl_training.ipynb", - "clean_ner_output": "72_pl_training.ipynb", - "NERInference": "72_pl_training.ipynb", - "CudaDevice": "CUDA_GPU_Management.ipynb", - "CudaHandler": "CUDA_GPU_Management.ipynb", - "MLMVisualizer": "bert_visualize.ipynb", - "li": "bert_visualize.ipynb", - "infer_logits": "bert_visualize.ipynb", - "predict_text": "bert_visualize.ipynb", - "visualize": "bert_visualize.ipynb", - "visualize_result": "bert_visualize.ipynb", - "softmax": "bert_visualize.ipynb", - "MLMVisualizer.infer_logits": "bert_visualize.ipynb", - "MLMVisualizer.predict_text": "bert_visualize.ipynb", - "MLMVisualizer.visualize": "bert_visualize.ipynb", - "MLMVisualizer.visualize_result": "bert_visualize.ipynb", - "split_df": "bilstm-based-search-on-netflix-data.ipynb", - "Vocab": "bilstm-based-search-on-netflix-data.ipynb", - "seqData": "bilstm-based-search-on-netflix-data.ipynb", - "arrData": "bilstm-based-search-on-netflix-data.ipynb", - "fuse": "bilstm-based-search-on-netflix-data.ipynb", - "MultiTaskCELoss": "cross_entropy_weighter.ipynb", - "Node": "dataframe_pipeline.ipynb", - "chunkNode": "dataframe_pipeline.ipynb", - "frameEdge": "dataframe_pipeline.ipynb", - "colEdge": "dataframe_pipeline.ipynb", - "donothing": "dataframe_pipeline.ipynb", - "nothing": "dataframe_pipeline.ipynb", - "fillNaEdge": "dataframe_pipeline.ipynb", - "engTokEdge": "dataframe_pipeline.ipynb", - "CNTok": "dataframe_pipeline.ipynb", - "capMinMaxEdge": "dataframe_pipeline.ipynb", - "trackVocabEdge": "dataframe_pipeline.ipynb", - "saveCSV": "dataframe_pipeline.ipynb", - "saveSQL": "dataframe_pipeline.ipynb", - "eng_twt_tk": "dataframe_pipeline.ipynb", - "Opts": "optimizers.ipynb"} - -modules = ["pdenhanced.py", - "imports.py", - "asyncing.py", - "df.py", - "html.py", - "widgets.py", - "flatten.py", - "spacy.py", - "freemap.py", - "multiproc.py", - "loop.py", - "etl.py", - "static_file.py", - "loopstack.py", - "config.py", - "minimum.py", - "editable.py", - "df_filter.py", - "files.py", - "wildtree.py", - "images/widgets.py", - "category.py", - "cosine.py", - "thunder/callbacks.py", - "hf/data.py", - "hf/train.py", - "ftorch/cuda.py", - "bert_visualize.py", - "data/nlp.py", - "multitask_ce.py", - "pipe.py", - "ftorch/optimizer.py"] - -doc_url = "https://raynardj.github.io/forgebox/" - -git_url = "https://github.com/raynardj/forgebox/tree/master/" - -def custom_doc_links(name): return None diff --git a/forgebox/asyncing.py b/forgebox/asyncing.py deleted file mode 100644 index 2316c3d..0000000 --- a/forgebox/asyncing.py +++ /dev/null @@ -1,55 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/03_async.ipynb (unless otherwise specified). - -__all__ = ['Async'] - -# Cell -import asyncio -from typing import Callable -def Async(func: Callable): - """ - JS style async tool - def download_file(url): - ... - return path - - download_async = Async(download_file) - - download_async(url)\ - .then(lambda x: os.system(f"tar -xvf {path}")) - .catch(logging.error) - - """ - class AsyncFunc: - f"""{func.__doc__}""" - def __init__(self): - self.success=[] - - async def afunc(self, *args, **kwargs): - try: - result = func(*args, **kwargs) - for success_func in self.success: - result = success_func(result) - except Exception as e: - self.catch_func(e) - - def __repr__(self): - return f"async function [{func}]" - - def __call__(self, *args, **kwargs): - f"{func.__doc__}" - self.args = args - self.kwargs = kwargs - self.success = [] - return self - - def then(self, success): - self.success.append(success) - return self - - def catch(self, catch): - assert len(self.success)>0,\ - "You have to define self.then first" - self.catch_func = catch - asyncio.gather(self.afunc(*self.args, **self.kwargs)) - - return AsyncFunc() \ No newline at end of file diff --git a/forgebox/batcher.py b/forgebox/batcher.py new file mode 100644 index 0000000..1feb95f --- /dev/null +++ b/forgebox/batcher.py @@ -0,0 +1,38 @@ +import math +from typing import Iterable, List, Any + + +class Batcher: + """ + To cut iterable to batch + # example + >>> for batch in Batcher([1,2,3,4,5],batch_size=2): + >>> print(batch) + [1, 2] + [3, 4] + [5] + """ + + def __init__(self, iterable: Iterable, batch_size: int = 512): + self.iterable = iterable + self.batch_size = batch_size + + def __repr__(self) -> str: + return f"Batched:{len(self)} batches, with batch size: {self.batch_size}" + + def __len__(self,) -> int: + idx = float(len(self.iterable))/float(self.batch_size) + return math.ceil(idx) + + def __getitem__(self, idx) -> List[Any]: + if idx >= len(self): + raise KeyError( + f"We have {len(self)} batch, your index is {idx}") + return self.iterable[idx*self.batch_size:(idx+1)*self.batch_size] + + def __iter__(self) -> Iterable: + for i in range(len(self)): + yield self.iterable[i*self.batch_size:(i+1)*self.batch_size] + + def one_batch(self) -> List[Any]: + return self[0] diff --git a/forgebox/bert_visualize.py b/forgebox/bert_visualize.py deleted file mode 100644 index 39089cb..0000000 --- a/forgebox/bert_visualize.py +++ /dev/null @@ -1,118 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/bert_visualize.ipynb (unless otherwise specified). - -__all__ = ['MLMVisualizer', 'li', 'infer_logits', 'predict_text', 'visualize', 'visualize_result', 'softmax'] - -# Cell -from .imports import * -from .config import Config -from .static_file import open_static -from jinja2 import Template -from .html import DOM -from uuid import uuid4 - -# Cell -class MLMVisualizer: - def __init__(self,model,tokenizer): - super().__init__() - self.model = model - self.tokenizer = tokenizer - - @classmethod - def from_pretrained(cls, - tag:"str, like how you use from_pretrained from transformers" - ): - obj = cls( - model = AutoModelForMaskedLM.from_pretrained(tag), - tokenizer = AutoTokenizer.from_pretrained(tag,use_fast=True), - ) - return obj - - def tok(self,text:str,)->[ - torch.FloatTensor, - torch.BoolTensor, - list, - ]: - """ - A specific way of tokenizing. - with pytorch tensor as input - with mask tensor specifying where's the [MASK] token - with offset mapping marking the positions - in format of list in list - """ - tokenized = self.tokenizer( - text, - return_tensors = "pt", - return_offsets_mapping=True - ) - x = tokenized['input_ids'] - offset_mapping = tokenized['offset_mapping'] - mask = x==self.tokenizer.mask_token_id - if len(offset_mapping.shape)==3: - offset_mapping=offset_mapping[0] - return x,mask,offset_mapping - -# Cell -softmax = nn.Softmax(dim=-1) - -def li(x,)->np.array: - if torch.is_tensor(x): - x=x.cpu().numpy() - return x.tolist() - -def infer_logits( - vis, - y_pred, - mask) -> Config: - logits = softmax(y_pred[mask]) - pred_idx = logits.argmax(-1) - return Config( - logits=logits, - pred_idx=pred_idx, - pred_tokens = vis.tokenizer.convert_ids_to_tokens(pred_idx) - ) - - -MLMVisualizer.infer_logits = infer_logits - -def predict_text( - vis, - text, - )->Config: - with torch.no_grad(): - x,mask,mapper=vis.tok(text) - y_pred,attention = vis.model(x,output_attentions=True) - infered = vis.infer_logits(y_pred,mask) - return Config( - text = text, - x = li(x), - mask = li(mask), - mapper = li(mapper), -# y_pred = li(y_pred), -# logits = li(infered.logits), - pred_idx=li(infered.pred_idx), - pred_tokens =infered.pred_tokens, - attention = list(map(li,attention)), - ) -MLMVisualizer.predict_text = predict_text - -def visualize(vis, - text): - result = vis.predict_text(text) - vis.visualize_result(result) - - -def visualize_result(vis, result: Config): - template = Template(open_static('mlm/visual.html')) - js = open_static('mlm/visual.js') - text = result.text - delattr(result, 'text') - output_id = str(uuid4()) - page = template.render(data=json.dumps(result), - text=text, - output_id=output_id, - mlm_visual_js=js) - DOM(page, "div",)() - - -MLMVisualizer.visualize = visualize -MLMVisualizer.visualize_result = visualize_result \ No newline at end of file diff --git a/forgebox/category.py b/forgebox/category.py index af2a05d..74fbe45 100644 --- a/forgebox/category.py +++ b/forgebox/category.py @@ -1,172 +1,8 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/53_category.ipynb (unless otherwise specified). - -__all__ = ['C2I', 'Category', 'TreeCategory'] - -# Cell -import pandas as pd -import numpy as np -from pathlib import Path -import json -from torch.utils.data.dataset import Dataset -from torch.utils.data.dataloader import DataLoader -from typing import Iterable, Dict, List - - -class C2I: - """ - Category to indices - >>> c2i = C2I( - ["class 1", "class 2", ..., "class n"], - pad_mst=True, - ) - >>> c2i[["class 2", "class 5"]] - [0] array([2,3]) - - If the indices you put in the slicing is a np.ndarray - a verctorized function will be used - """ - - def __init__( - self, - arr: Iterable, - pad_mst: bool = False, - ): - self.pad_mst = pad_mst - self.pad = ["[MST]", ] if self.pad_mst else [] - self.dict = dict( - (v, k) for k, v in enumerate(self.pad + list(arr))) - self.get_int = self.get_get_int() - self.get_int_ = np.vectorize(self.get_int) - - def get_get_int(self,): - if self.pad_mst: - def get_int(idx: str) -> int: - if idx in self.dict: - return self.dict[idx] - else: - return 0 - else: - def get_int(idx: str) -> int: - return self.dict[idx] - return get_int - - def __repr__(self) -> str: - return f"C2I:{self.__len__()} categories" - - def __len__(self): - return len(self.dict) - - def __getitem__(self, k: int): - if type(k) in [np.ndarray, list]: - # use vectorized function - return self.get_int_(k) - else: - # use the original python function - return self.get_int(k) - - -class Category: - """ - Manage categorical translations - c = Category( - ["class 1", "class 2", ..., "class n"], - pad_mst=True,) - - c.c2i[["class 3","class 6"]] - c.i2c[[3, 2, 1]] - """ - - def __init__( - self, - arr: Iterable, - pad_mst: bool = False - ): - self.pad_mst = pad_mst - self.c2i = C2I(arr, pad_mst=pad_mst) - self.i2c = np.array(self.c2i.pad+list(arr)) - - def save(self, path: Path) -> None: - """ - save category information to json file - """ - with open(path, "w") as f: - json.dump(self.i2c.tolist(), f) - - @classmethod - def load(cls, path: Path): - """ - load category information from a json file - """ - with open(path, "r") as f: - l = np.array(json.load(f)) - if l[0] == "[MST]": - return cls(l[1:], pad_mst=True) - else: - return cls(l, pad_mst=False) - - def __len__(self): - return len(self.i2c) - - def __repr__(self): - return f"Category Manager with {self.__len__()}" - - -class TreeCategory(Category): - """ - Manage categorical translations - c = Category( - ["class 1", "class 2", ..., "class n"], - pad_mst=True,) - - c.c2i[["class 3","class 6"]] - c.i2c[[3, 2, 1]] - """ - - def __init__( - self, - parent_map: Dict[str, str], - pad_mst: bool = False - ): - self.parent_map = parent_map - arr = np.array(list(self.parent_map.keys())) - super().__init__(arr, pad_mst=pad_mst) - self.ancestor_map = dict() - for name in self.parent_map.keys(): - self.find_ancestor_map(name) - - self.get_depth_map() - self.get_depth_map_array() - - def find_ancestor_map( - self, name: str - ) -> Dict[str, List[str]]: - if name in self.ancestor_map: - return self.ancestor_map[name] - if name not in self.parent_map: - return [] - else: - result = [name, ]+self.find_ancestor_map(self.parent_map[name]) - self.ancestor_map[name] = result - return result - - - def tree_hot(self, name: str) -> np.array: - """ - return tree hot encoding name according to category - """ - target = np.zeros(len(self), dtype=int) - target[self.c2i[self.ancestor_map[name]]]=1 - return target - - def get_depth_map(self) -> Dict[str, int]: - self.depth_map = dict( - (k, len(v)) for k,v in self.ancestor_map.items()) - return self.depth_map - - def get_depth_map_array(self) -> np.array: - self.depth_map_array = np.vectorize( - self.depth_map.get)(self.i2c) - return self.depth_map_array - - def __repr__(self): - return f"""Tree Category({len(self)}):\n\tself.tree_hot("name")\tself.ancestor_map\tself.depth_map_array""" \ No newline at end of file +from category import ( + Category, MultiCategory, C2I +) + +from category.fast import ( + Category as FastCategory, + MultiCategory as FastMultiCategory +) diff --git a/forgebox/config.py b/forgebox/config.py index ac9377f..ec0d028 100644 --- a/forgebox/config.py +++ b/forgebox/config.py @@ -1,12 +1,6 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/20_config.ipynb (unless otherwise specified). - -__all__ = ['Config', 'first', 'getall'] - -# Cell import json -from datetime import datetime -# Cell + class Config(dict): def __setattr__(self,k,v): self[k]=v @@ -73,4 +67,4 @@ def getall(d,key): if type(d) in [tuple,list,set]: for i in d: results += getall(i,key) - return results \ No newline at end of file + return results diff --git a/forgebox/cosine.py b/forgebox/cosine.py index 6754254..ce674c6 100644 --- a/forgebox/cosine.py +++ b/forgebox/cosine.py @@ -1,13 +1,8 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/55_cosine_search.ipynb (unless otherwise specified). - -__all__ = ['CosineSearch', 'CosineSearchWithCategory'] - -# Cell import numpy as np import pandas as pd -from .category import Category +from category import Category + -# Cell class CosineSearch: """ Build a index search on cosine distance @@ -24,7 +19,7 @@ def __init__(self, base): self.normed_base = self.base/self.base_norm[:, None] self.dim = self.base.shape[1] - def __len__(self): return base.shape[0] + def __len__(self): return self.base.shape[0] @staticmethod def calc_base_norm(base: np.ndarray) -> np.ndarray: @@ -54,7 +49,7 @@ class CosineSearchWithCategory(CosineSearch): search_dataframe """ - def __init__(self, base: np.ndarray, category: np.ndarray): + def __init__(self, base: np.ndarray, category: Category): super().__init__(base) self.category = category assert len(self.category) >= len(self), "category number too small" @@ -75,4 +70,4 @@ def search_dataframe( idx = self.search(vec, return_similarity) return pd.DataFrame({ "category": self.category.i2c[idx], - "idx": idx}) \ No newline at end of file + "idx": idx}) diff --git a/forgebox/data/__init__.py b/forgebox/data/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/forgebox/data/nlp.py b/forgebox/data/nlp.py deleted file mode 100644 index 2781f11..0000000 --- a/forgebox/data/nlp.py +++ /dev/null @@ -1,169 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/bilstm-based-search-on-netflix-data.ipynb (unless otherwise specified). - -__all__ = ['split_df', 'Vocab', 'seqData', 'arrData', 'fuse'] - -# Cell -import numpy as np # linear algebra -import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv) -import os -from pathlib import Path -# Any results you write to the current directory are saved as output. - -# Cell -def split_df(df, valid=0.2, ensure_factor=2): - """ - df: dataframe - valid: valid ratio, default 0.1 - ensure_factor, ensuring the row number to be the multiplication of this factor, default 2 - return train_df, valid_df - """ - split_ = (np.random.rand(len(df)) > valid) - train_df = df[split_].sample(frac=1.).reset_index().drop("index", axis=1) - valid_df = df[~split_].sample(frac=1.).reset_index().drop("index", axis=1) - - if ensure_factor: - train_mod = len(train_df) % ensure_factor - valid_mod = len(valid_df) % ensure_factor - if train_mod: train_df = train_df[:-train_mod] - if valid_mod: valid_df = valid_df[:-valid_mod] - return train_df, valid_df - -# Cell -from itertools import chain -from multiprocessing import Pool -from collections import Counter -from torch.utils.data.dataset import Dataset - -class Vocab(object): - def __init__(self, iterative, tokenize, max_vocab = 20000,nproc=10): - """ - Count the most frequent words - Make the word<=>index mapping - """ - self.l = list(iterative) - self.nproc = nproc - self.max_vocab = max_vocab - self.tokenize = tokenize - self.word_beads = self.word_beads_() - self.counter() - - def __len__(self): - return len(self.words) - - def __repr__(self): - return f"vocab {self.max_vocab}" - - def word_beads_(self): - self.p = Pool(self.nproc) - return list(chain(*list(self.p.map(self.tokenize,self.l)))) - - def counter(self): - vals = np.array(list((k,v) for k,v in dict(Counter(self.word_beads)).items())) - self.words = pd.DataFrame({"tok":vals[:,0],"ct":vals[:,1]}) - self.words["ct"] = self.words["ct"].apply(int) - self.words = self.words.sort_values(by= "ct",ascending=False)\ - .reset_index().drop("index",axis=1).head(self.max_vocab-2) - self.words["idx"] = (np.arange(len(self.words))+2) - self.words=pd.concat([self.words,pd.DataFrame({"tok":["",""],"ct":[-1,-1],"idx":[0,1]})]) - return self.words - - def to_i(self): - self.t2i = dict(zip(self.words["tok"],self.words["idx"])) - def to_index(t): - i = self.t2i.get(t) - if i==None: - return 1 - else: - return i - return to_index - - def to_t(self): - return np.roll(self.words["tok"],2) - - -# Cell - -import torch -from torch.utils.data.dataloader import DataLoader -from torch.utils.data._utils.collate import default_collate - -class seqData(Dataset): - def __init__(self,lines,vocab,max_len=-1): - """ - lines: iterative of text, eg. each element a sentence - vocab:forge.data.nlp.Vocab - max_len: max length - """ - self.lines = list(lines) - self.vocab = vocab - self.to_i = np.vectorize(vocab.to_i()) - self.to_t = vocab.to_t() - self.bs=1 - self.max_len=max_len - - def __len__(self): - return len(self.lines) - - def __getitem__(self,idx): - """ - Translate words to indices - """ - line = self.lines[idx] - words = self.vocab.tokenize(line) - if self.max_len>2: - words = words[:self.max_len-2] - words = ["",]+words+[""] - return self.to_i(np.array(words)) - - def backward(self,seq): - """ - This backward has nothing to do with gradrient - Just to error proof the tokenized line - """ - return " ".join(self.to_t[seq]) - - def collate(self,rows): - """ - this collate will pad any sentence that is less then the max length - """ - line_len = torch.LongTensor(list(len(row) for row in rows)); - max_len = line_len.max() - ones = torch.ones(max_len.item()).long() - line_pad = max_len-line_len - return torch.stack(list(torch.cat([torch.LongTensor(row),ones[:pad.item()]]) for row,pad in zip(rows,line_pad[:,None]))) - -class arrData(Dataset): - def __init__(self, *arrs): - self.arr = np.concatenate(arrs,axis=1) - - def __len__(self): - return self.arr.shape[0] - - def __getitem__(self,idx): - return self.arr[idx] - - def collate(self,rows): - return default_collate(rows) - -# Cell -class fuse(Dataset): - def __init__(self, *datasets): - """ - A pytorch dataset combining the dataset - :param datasets: - """ - self.datasets = datasets - length_s = set(list(len(d) for d in self.datasets)) - assert len(length_s) == 1, "dataset lenth not matched" - self.length = list(length_s)[0] - self.collates = list(i.collate if hasattr(i,"collate") else default_collate for i in datasets) - - def __len__(self): - return self.length - - def __getitem__(self, idx): - return tuple(d.__getitem__(idx) for d in self.datasets) - - def collate(self,rows): - xs = list(zip(*rows)) - return tuple(func(x) for func, x in zip(self.collates,xs)) \ No newline at end of file diff --git a/forgebox/df.py b/forgebox/df.py index 5102170..9a89ee3 100644 --- a/forgebox/df.py +++ b/forgebox/df.py @@ -5,23 +5,25 @@ # Cell import pandas as pd + class PandasDisplay: """ - Temporary pandas display config "with" hook + Temporary pandas display config "with" scope with PandasDisplay(max_colwidth = 0,max_rows=100): display(df) """ - def __init__(self,**kwargs): + + def __init__(self, **kwargs): self.kwargs = kwargs self.cache = dict() def __enter__(self): - for k,v in self.kwargs.items(): + for k, v in self.kwargs.items(): self.cache[k] = pd.get_option(f"display.{k}") - pd.set_option(f"display.{k}",v) + pd.set_option(f"display.{k}", v) return self def __exit__(self, type, value, tb): - for k,v in self.cache.items(): - pd.set_option(f"display.{k}",v) \ No newline at end of file + for k, v in self.cache.items(): + pd.set_option(f"display.{k}", v) diff --git a/forgebox/df_filter.py b/forgebox/df_filter.py deleted file mode 100644 index e8149f8..0000000 --- a/forgebox/df_filter.py +++ /dev/null @@ -1,308 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/31_df_filter.ipynb (unless otherwise specified). - -__all__ = ['pct_to_float', 'ensure_pct', 'detect_number_column', 'DataFilter', 'LayerTorch', 'RecursiveFilterCore', - 'RecursiveFilter'] - -# Cell -from abc import ABC -from typing import List, Callable -from .html import DOM -from .imports import pd, np - -# Cell -from ipywidgets import VBox, Button,\ - FloatSlider, IntSlider, SelectionSlider,Dropdown, Label,Checkbox,\ - interact, Output, interact_manual - - -def pct_to_float(x): - if type(x)!=str: return x - if "%" not in x: - return x - else: - return float(x[:-1])/100 - -def ensure_pct(df): - for col in df: - if df[col].dtype.name=="object": - df[col] = df[col].apply(pct_to_float) - return df - -def detect_number_column(df): - """ - Detect number columns in dataframe - """ - cols = df.columns - dtypes = [df[col].dtype.name for col in cols] - return pd.DataFrame({"cols":cols, "dtypes":dtypes}) - -class DataFilter: - """ - Single column number filter - """ - def __init__(self, df: pd.DataFrame, fix_pct=True): - """ - df: input dataframe - - data_filter = DataFilter(df) - - # start filtering - data_filter() - """ - self.df = df - - if fix_pct: - self.df = ensure_pct(self.df) - - def show_distribution(self, col_name): - """ - show distribution of a column, using plotly - """ - import plotly.express as px - fig = px.histogram(self.df, x=col_name, height=300, width=800) - return fig - - def create_filter(self, field: str) -> None: - big_boxes = [] - - dtype = self.df[field].dtype.name - if 'float' in dtype: - slider = FloatSlider - slide = slider( - min = self.df[field].min(), - max = self.df[field].max(), - step = 0.001 - ) - elif 'int' in dtype: - slider = IntSlider - slide = slider( - min = self.df[field].min(), - max = self.df[field].max(),) - else: - print(f"filter of {dtype} not supported") - slider = SelectionSlider - slide = slider(options=sorted(map(str, set(list(self.df[field]))))) - - btn = Button(description="Run Filter") - btn.on_click(self.execute_filter) - - print(f"NaN count: {(self.df[field].isna()).sum()}") - - widget = VBox([ - Label(f"Range for {field}"), - Dropdown(options=["Larger Than or equal to", "Smaller Than or equal to"]), - slide, - Checkbox(description="Remove NaN", value=True), - btn - ]) - self.widget = widget - widget.original_name = field - - display(widget) - - def execute_filter( - self, _) -> None: - """ - This function will be used as a callback - for ipywidgets.Button.on_click - """ - original_name = self.widget.original_name - label_,condi_,value_,remove_na_, btn_ = self.widget.children - label, condi, value, remove_na = label_.value ,condi_.value ,value_.value, remove_na_.value - condi = ">=" if condi=='Larger Than or equal to' else "<=" - if type(value_)==SelectionSlider: - value = f"'{value}'" - expression = f"{original_name} {condi} {value}" - - if remove_na: - self.remove_na(original_name) - - print(f"Filter with query expression: {expression}") - before = len(self.df) - self.df = self.df.query(expression).reset_index(drop=True) - after = len(self.df) - print(f"[Before]: {before}, [After]: {after}") - - def remove_na(self, field): - """ - Remove nan value in a dataframe - """ - before = len(self.df) - self.df = self.df[~self.df[field].isna()] - after = len(self.df) - print(f"Remove NA on {field} [Before]: {before}, [After]: {after}") - - def __call__(self, columns=None): - """ - Execute an interact to filter things column by column - """ - columns = columns if columns else list(self.df.columns) - @interact - def select_field(field = columns): - # visualize histogram - self.show_distribution(field).show() - - # create a filter execution interactive - self.create_filter(field) - -# Cell -class LayerTorch: - """ - information passon from layer to layer - """ - def __init__(self, df, level=0,last_layer=None): - self.df = df - self.level = level - self.data = dict() - if last_layer is not None: - self.last_layer = last_layer - self.out = Output() - if last_layer is None: - self.axis = dict() - df.filter_layers = self.axis - else: - self.axis = last_layer.axis - self.axis[level] = self - - def __call__(self, **kwargs): - self.data.update(kwargs) - for k, v in kwargs.items(): - setattr(self, k, v) - - def __repr__(self): - return f"Level:{self.level}\n\t{self.data}" - - def next_layer(self): - new = LayerTorch(self.df, level=self.level+1, last_layer=self) - self.next_layer = new - return new - - @property - def layers(self) -> pd.DataFrame: - """ - Filter layers as a pandans dataframe - """ - return pd.DataFrame( - list(i.data for i in self.axis.values())) - - @property - def filter_chain(self) -> str: - query_list = list(i.data["query"] for i in self.axis.values()) - return ' and '.join(list(f"({q})" for q in query_list)) - -class RecursiveFilterCore(ABC): - - def display_queries(self, this_layer): - if this_layer.level > 0: - DOM("Queried Filters","h3", )() - display(this_layer.layers[:-1]) - - def handpick( - self, - chunk_callbacks: List[Callable]=[], - show_top: bool=True, - show_top_k: int=20, - pick_value_top_k: int=30, - from_last_layer: LayerTorch=None - ) -> None: - """ - Hand pick the portion of the data frame you liked - from filtering the column by value. - A function from enhanced pandas dataframe - - Inputs: - - chunk_callbacks: List[Callable]=[], - - show_top: bool, default True, do we should - the most frequent values of the current column - - show_top_k: int, the number of rows we show for - the most frequent values, when show_top=True, - default 20 - - pick_value_top_k: int, number of the most frequent - values in pick drop down default 30 - - from_last_layer: LayerTorch, default None, this - column doesn't mean for user configuration - """ - this_layer = LayerTorch(self) if from_last_layer is None else from_last_layer.next_layer() - display(this_layer.out) - - with this_layer.out: - self.display_queries(this_layer) - - DOM("Select Filter Column","h3")() - @interact - def select_columns(column = self.columns): - - this_layer(column=column) - series = self[column] - vc = self.vc(column) - - if show_top: - display(vc.head(show_top_k)) - - this_layer.out.played = True - - top_values = list(vc.index) - if pick_value_top_k is not None: - top_values = top_values[:pick_value_top_k] - - DOM(f"'{column}' equals to ?","h3", )() - - @interact() - def pick_value(picked = top_values): - query = f"`{column}`=='{picked}'" - sub = RecursiveFilter(self.query(query)) - - # keep record on this layer - this_layer( - query = query, - picked=picked, - before_rows=len(self), - after_rows=len(sub) - ) - - for cb in chunk_callbacks: - cb(sub) - - @interact_manual - def start_recursion(): - this_layer.out.clear_output() - - with this_layer.out: - - # Recursion - # Go on the filter to the next layer - sub.handpick( - chunk_callbacks=chunk_callbacks, - show_top=show_top, - show_top_k=show_top_k, - pick_value_top_k=pick_value_top_k, - from_last_layer=this_layer, - ) - - sub.paginate(10) - - - -class RecursiveFilter(pd.DataFrame, RecursiveFilterCore): - """ - Interactive Pandas DataFrame Filter - df = RecursiveFilter(df) - df.handpick() - - Hand pick the portion of the data frame you liked - from filtering the column by value. - A function from enhanced pandas dataframe - - Inputs: - - chunk_callbacks: List[Callable]=[], - - show_top: bool, default True, do we should - the most frequent values of the current column - - show_top_k: int, the number of rows we show for - the most frequent values, when show_top=True, - default 20 - - pick_value_top_k: int, number of the most frequent - values in pick drop down default 30 - - from_last_layer: LayerTorch, default None, this - column doesn't mean for user configuration - """ - pass \ No newline at end of file diff --git a/forgebox/editable.py b/forgebox/editable.py deleted file mode 100644 index 3225dcb..0000000 --- a/forgebox/editable.py +++ /dev/null @@ -1,137 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/30_traceable_edit_in_flask.ipynb (unless otherwise specified). - -__all__ = ['get_static', 'edit_js', 'DefaultTemp', 'Editable'] - -# Cell -import pandas as pd -from datetime import datetime -import json -from sqlalchemy import create_engine as ce -from sqlalchemy import text -from jinja2 import Template - -# Cell -from pathlib import Path -def get_static(): - import forgebox - return Path(forgebox.__path__[0])/"static" - -# Cell -def edit_js(): - with open(get_static()/"edit.js","r") as f: - return f"" - - -class DefaultTemp(Template): - """ - Jinjia template with some default render config - """ - def render(self,dt): - dt.update(dict(type=type,now = datetime.now())) - return super().render(dt) - -# Cell -from flask import request -from flask import g -from datetime import datetime - -class Editable: - def __init__(self,name,app,table_name,con,id_col, - log_con,log_table="editable_log",columns = None): - """ - name: route name for url path, - also it will be the task title appearning on the frontend - app:flask app - table_name: table to edit - con:sqlachemy connnection, created by : con = sqlalchemy.create_engine - id_col: a column with unique value - log_con:sqlachemy connnection, for storaging change log - """ - self.name = name - self.app = app - self.table_name = table_name - self.con = con - self.log_con = log_con - self.columns = ",".join(columns) if columns!=None else "*" - self.id_col = id_col - - self.t_workspace = self.load_temp(get_static()/"workspace.html") - self.t_table = self.load_temp(get_static()/"table.html") - self.assign() - - def assign(self): - self.app.route(f"/{self.name}")(self.workspace) - self.app.route(f"/{self.name}/df_api")(self.read_df) - self.app.route(f"/{self.name}/save_api", - methods=["POST"])(self.save_data) - - def workspace(self): - return self.t_workspace.render(dict(title=self.name, - pk=self.id_col, - edit_js = edit_js())) - - def save_data(self): - data = json.loads(request.data) - # update change and save log - changes = data["changes"] - log_df = pd.DataFrame(list(self.single_row(change) for change in changes)) - - log_df["idx"] = log_df.idx.apply(str) - log_df["original"] = log_df.original.apply(str) - log_df["changed"] = log_df.changed.apply(str) - log_df.to_sql(f"editable_log",con = self.log_con,index=False, if_exists="append") - - print(log_df) - # return updated table - query = data["query"] - page = query["page"] - where = query["where"] - return self.data_table(page,where) - - def settype(self,k): - if k[:3] == "int": return int - elif "float" in k: return float - elif k=="str":return str - elif k=="list":return list - elif k=="dict":return dict - else: return eval(k) - - def single_row(self,row): - row["ip"]= request.remote_addr - row["table_name"] = self.table_name - row["ts"] = datetime.now() - if row["original"]==row["changed"]: - row['sql'] = "" - return row - else: - col = row["col"] - val = row["changed"] - val = f"'{val}'" if 'str' in row["valtype"] else val - idx = row["idx"] - idx = f"'{idx}'" if type(idx)==str else idx - set_clause = f"SET {col}={val}" - sql = f"""UPDATE {self.table_name} - {set_clause} WHERE {self.id_col}={idx} - """ - row['sql'] = sql - self.con.execute(sql) - return row - - def read_df(self): - page = request.args.get('page') - where = request.args.get('where') - return self.data_table(page,where) - - def data_table(self,page,where): - where_clause = "" if where.strip() == "" else f"WHERE {where} " - sql = f"""SELECT {self.columns} FROM {self.table_name} {where_clause} - ORDER BY {self.id_col} ASC LIMIT {page},20 - """ - print(sql) - df = pd.read_sql(sql,self.con) - df = df.set_index(self.id_col) - return self.t_table.render(dict(df = df)) - - def load_temp(self,path): - with open(path, "r") as f: - return DefaultTemp(f.read()) \ No newline at end of file diff --git a/forgebox/etl.py b/forgebox/etl.py deleted file mode 100644 index 77ad3cc..0000000 --- a/forgebox/etl.py +++ /dev/null @@ -1,67 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/11_etl.ipynb (unless otherwise specified). - -__all__ = ['NewFileScanner'] - -# Cell - -from .imports import * -from typing import Callable, Union -import traceback as tb -import logging - -class NewFileScanner: - """ - Keep scannning a directory for new file - if found any, callback processing the file - - Designed for download and delete strategy - - # Example - new_file_scanner = NewFileScanner(".", new_file_filter=lambda x:x[-4:]==".txt") - new_file_scanner(lambda x:print(f"new file:{x} found"))s - """ - def __init__( - self, - directory, - new_file_filter: Callable=None, - done_list_getter: Callable=None, - stop_callback: Callable=None, - ): - self.directory = Path(directory) - - if new_file_filter is not None: - self.new_file_filter=new_file_filter - else: - self.new_file_filter=lambda x:True - - if done_list_getter is not None: - self.done_list_getter = done_list_getter - else: - self.done_list_getter = lambda *args:[] - - if stop_callback is not None: - self.stop_callback = stop_callback - - self.processed = [] - - def __call__(self, process: Callable): - while True: - try: - done_list = self.done_list_getter() - for fname in self.directory.iterdir(): - fname = str(fname) - if self.new_file_filter(fname) != True: - continue - file_path = str(self.directory/fname) - if fname not in done_list: - if fname not in self.processed: - result = process(file_path) - self.processed.append(fname) - except KeyboardInterrupt as e: - if hasattr(self, "stop_callback"): - self.stop_callback() - logging.error("manually stoped") - break - except Exception as e: - error = tb.format_exc() - logging.error(error) \ No newline at end of file diff --git a/forgebox/files.py b/forgebox/files.py index c9a51e8..8a74a6c 100644 --- a/forgebox/files.py +++ b/forgebox/files.py @@ -2,28 +2,28 @@ __all__ = ['get_files', 'file_detail'] -# Cell from typing import Union, List from .imports import Path, pd + def get_files( path: Path, - skip: Union[str, List[str]]=None + skip: Union[str, List[str]] = None ) -> pd.DataFrame: """Get all file paths from a directory""" path = Path(path).absolute() files = [] if type(skip) == str: - def not_skipping(phrase)->bool: + def not_skipping(phrase) -> bool: return skip in phrase elif type(skip) == list: - def not_skipping(phrase)->bool: + def not_skipping(phrase) -> bool: for sk in skip: if sk in phrase: return True return False elif skip is None: - not_skipping = lambda x:True + def not_skipping(x): return True else: raise TypeError( f"type of skip not correct: {type(skip)}") @@ -39,14 +39,16 @@ def get_files_(p: Path) -> None: return pd.DataFrame(dict(path=files)) + def file_detail( path: Path, - skip: Union[str, List[str]]=None + skip: Union[str, List[str]] = None ) -> pd.DataFrame: """ Get detailed file information from a directory """ file_df = get_files(path, skip=skip) + def find_type(x): try: x = Path(x) @@ -77,4 +79,4 @@ def find_depth(x): file_df["parent"] = file_df.path.apply(find_parent) file_df["depth"] = file_df.path.apply(find_depth) - return file_df \ No newline at end of file + return file_df diff --git a/forgebox/flatten.py b/forgebox/flatten.py deleted file mode 100644 index b7710bb..0000000 --- a/forgebox/flatten.py +++ /dev/null @@ -1,43 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/06_flatten.ipynb (unless otherwise specified). - -__all__ = ['Flatten'] - -# Cell - -from typing import List, Callable, Any, Dict -class Flatten: - """ - Flatten a tree structure dictionary - """ - def __init__( - self, data, - key_callback: Callable = None, - key_connection: str = "_", - ): - self.data = data - self.key_callback = key_callback - self.key_connection = key_connection - - def flattening( - self, data, - result=None, - upper_key="" - ) -> Dict[str, str]: - """ - Recursive flatten function - """ - if result is None: - result = {} - for key, value in data.items(): - if self.key_callback is not None: - key = self.key_callback(key) - if isinstance(value, dict): - self.flattening(value, result, - upper_key=f"{key}{self.key_connection}") - else: - result[f"{upper_key}{key}"] = value - return result - - def __call__(self) -> Dict[str, str]: - return self.flattening(self.data) - diff --git a/forgebox/freemap.py b/forgebox/freemap.py deleted file mode 100644 index 8f4074f..0000000 --- a/forgebox/freemap.py +++ /dev/null @@ -1,83 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/07_freemap.ipynb (unless otherwise specified). - -__all__ = ['FreeMap'] - -# Cell -from collections import OrderedDict - -# Cell -class FreeMap: - def __init__(self, - func= lambda x:x, - filter_function = lambda x: True, - flatten = False): - """ - run map operation on a free stucture, - like dictionary, list within dictionary, etc - - """ - self.func = func - self.filter_function = filter_function - self.flatten = flatten - if flatten: - self.result_list = [] - self.create_doc() - - def __repr__(self): - return f""" - Please put in one of the following type: - dict, list, tuple, set, OrderedDict - - {self.keep_structure} - ====== - Mapped function - {self.func} - Value Filter function - {self.filter_function} - """ - - @property - def keep_structure(self): - return "This operation will flatten the structure to a list"\ - if self.flatten else\ - "This operation will keep the original structure" - - def create_doc(self): - doc = f""" - map function for list,dict,tuple,set,OrderedDict - {self.keep_structure} - - """ - if hasattr(self.func,"__doc__"): - if self.func.__doc__!=None: - doc += f"doc string from mapping function:\n\t\t{self.func.__doc__}\t" - setattr(self,"__doc__",doc) - - def parse(self,thing): - if type(thing) in [list,tuple,set]: - return self.parse_seq(thing) - elif type(thing) in [dict,OrderedDict]: - return self.parse_kv(thing) - else: - return self.parse_value(thing) - - def parse_seq(self,thing): - return type(thing)(self.parse(i) for i in thing) - - def parse_kv(self,thing): - return type(thing)((k,self.parse(v)) for k,v in thing.items()) - - def parse_value(self,thing): - if self.filter_function(thing): - if self.flatten==False: - return self.func(thing) - else: - self.result_list.append(self.func(thing)) - return thing - - def __call__(self,iterable): - result = self.parse(iterable) - if self.flatten: - return self.result_list - else: - return result \ No newline at end of file diff --git a/forgebox/ftorch/README.md b/forgebox/ftorch/README.md deleted file mode 100644 index 0b9ae4e..0000000 --- a/forgebox/ftorch/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# ftorch: A pytorch API to forge - -### Preprocessor -forgebox contains data pre-processing module for pytorch. - -It returns pytorch dataset -```python -from forgebox.ftorch.prepro import DF_Dataset,fuse -train_ds_x = DF_Dataset(train_df, # pandas dataframe for training - prepro=x_prepro, # x_prepro is the function: input a chunk of dataframe, return same len of data in numpy array - bs=64, # batch_size - shuffle=False) -# train_ds_x will be a pytorch dataset -train_ds_y = DF_Dataset(train_df,prepro=y_prepro,bs=64,shuffle=False) -``` -fuse combines 2 datasets together, -```python -train_ds = fuse(train_ds_x,train_ds_y) -``` -we can use it like ```x,y = next(iter(train_ds))``` - -### Trainer -```python -from forgebox.ftorch.train import Trainer - -trainer=Trainer(train_ds, val_dataset = valid_ds ,batch_size=1,print_on=2) -trainer.opt["adm1"] = torch.opt.Adam(model.parameters()) -``` - -#### A training step -we use the step_train decorator to define a training step -```python -from forgebox.ftorch.metrics import metric4_bi - -@trainer.step_train -def action(self): - x,y = self.data - x = x.squeeze(0) - y = y.float() - opt.zero_grad() - y_ = model(x) - loss = loss_func(y_,y) - acc, rec, prec, f1 = metric4_bi(y_,y) - loss.backward() - self.opt.adm.step() - return {"loss":loss.item(),"acc":acc.item(),"rec":rec.item(),"prec":prec.item(),"f1":f1.item()} -``` -The above is only an example, you can define the training step as you like. - -Even if you have 3 models, updated by 2 optimizers, as long as you can decribe them in a single training step, it can be done easily. - -#### A validation step -Very similar to the train step, minus any code relate to updating weights - -```python -@trainer.step_val # step_val decorator -def val_action(self) - x,y = self.data - x = x.squeeze(0) - y = y.float() - y_ = model(x) - ... -``` - -Then run the training for 3 epochs like: - -```python -trainer.train(3) -``` \ No newline at end of file diff --git a/forgebox/ftorch/callbacks.py b/forgebox/ftorch/callbacks.py deleted file mode 100644 index 2c0c980..0000000 --- a/forgebox/ftorch/callbacks.py +++ /dev/null @@ -1,29 +0,0 @@ -import pandas as pd -from datetime import datetime -from .utils import mars - -def recorddf(record): - return pd.DataFrame(record) - -## The following are the callbacks for trainer - -def print_all(record): - df = recorddf(record) - mars(df) - - -def stat(record): - """ - Print out track statistics - :param record: self.track[epoch] in trainer.run(self.epoch) - :param dataset: train dataset or val_dataset - """ - df = recorddf(record) - start = datetime.strptime(list(df["ts"])[0], "%Y-%m-%d %H:%M:%S.%f").timestamp() - end = datetime.strptime(list(df["ts"])[-1], "%Y-%m-%d %H:%M:%S.%f").timestamp() - - des = df.describe().loc[["mean", "min", "max"], :] - des["timestamp"] = [(end - start) / len(df), 0, end - start] - mars(des) - - diff --git a/forgebox/ftorch/cuda.py b/forgebox/ftorch/cuda.py index e7d4cc6..48975a2 100644 --- a/forgebox/ftorch/cuda.py +++ b/forgebox/ftorch/cuda.py @@ -1,8 +1,3 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/CUDA_GPU_Management.ipynb (unless otherwise specified). - -__all__ = ['CudaDevice', 'CudaHandler'] - -# Cell import torch import subprocess @@ -49,11 +44,11 @@ def refresh(self): def __call__(self): return self.device -# Cell -class CudaHandler(object): + +class Cudas(object): def __init__(self): """ - ch = CudaHandler() + ch = Cudas() dev = ch.idle()() some_torch_tensor.to(dev) """ @@ -103,4 +98,6 @@ def idle(self): if d.free > rt.free: rt = d print(f"Found the most idle GPU: cuda:{rt.idx}, {rt.free} MB Mem remained") - return rt \ No newline at end of file + return rt + +CudaHandler = Cudas \ No newline at end of file diff --git a/forgebox/ftorch/optimizer.py b/forgebox/ftorch/optimizer.py index 1e064c6..4b4a53f 100644 --- a/forgebox/ftorch/optimizer.py +++ b/forgebox/ftorch/optimizer.py @@ -1,9 +1,5 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/optimizers.ipynb (unless otherwise specified). - __all__ = ['Opts'] -# Cell -import torch class Opts(object): def __init__(self, *args, **kwargs): diff --git a/forgebox/ftorch/prepro.py b/forgebox/ftorch/prepro.py index 7231d6e..6a55aed 100644 --- a/forgebox/ftorch/prepro.py +++ b/forgebox/ftorch/prepro.py @@ -1,269 +1,16 @@ import random from torch.utils.data import Dataset, DataLoader -import math -import os import torch -import pandas as pd import numpy as np -from collections import Counter from typing import Callable -class Empty(Dataset): - def __init__(self, length): - """ - empety dataset, spit out random number - :param length: how long you want this dataset - """ - self.length = length - self.seq = np.random.rand(length, 2) - - def __len__(self): - return self.length - - def __getitem__(self, idx): - return self.seq[idx] - - -class DF_Dataset(Dataset): - def __init__( - self, df, bs, - prepro=lambda x: x.values, - shuffle: bool = False, - col: str = None - ): - """ - df_dataset, a dataset for slicing pandas dataframe, - instead of single indexing and collate - Please use batch_size=1 for dataloader, and define the batch size here - eg. - ``` - ds = DF_Dataset(data_df,bs=1024) - ``` - """ - # super(DF_Dataset, self).__init__() - - if shuffle: - print("shuffling") - df = df.sample(frac=1.).reset_index().drop("index", axis=1) - print("shuffled") # shuffle the data here - - if col: - df = df[col] - self.df = df - self.prepro = prepro - self.bs = bs - - def __len__(self): - return math.ceil(len(self.df) / self.bs) - - def __getitem__(self, idx): - start = idx * self.bs - end = (idx + 1) * self.bs - return self.prepro(self.df[start:end]) - - -class Arr_Dataset(Dataset): - def __init__(self, *args, bs): - """ - arr_dataset, a dataset for slicing numpy array, - instead of single indexing and collate - Please use batch_size=1 for dataloader, and define the batch size here - eg. - ``` - ds = Arr_Dataset(arr_1,arr_2,arr_3,bs = 512) - ``` - """ - super(Arr_Dataset, self).__init__() - self.arrs = args - self.bs = bs - - def __len__(self): - return math.ceil(len(self.arrs[0]) / self.bs) - - def __getitem__(self, idx): - start = idx * self.bs - end = (idx + 1) * self.bs - return tuple(self.arrs[i][start:end] for i in range(len(self.arrs))) - - -class Seq_Dataset(Dataset): +class ZipDataset(Dataset): """ - a mechanism for reading sequence data, - the preparation stage of nlp learning + ZipDataset the dataset into one """ - def __init__( - self, - seqname, - seq, - seq_len: int = None, - vocab_path: str = None, - bs: int = 16, - vocab_size: int = 10000, - build_vocab: bool = False, - sep_tok: str = "", - discard_side: str = "right", - element_type: str = "int", - fixlen: bool = False - ): - ''' - A pytorch dataset for sequence - seq: enumerable sequence - vocab_path: path to vocabulary json file - threads:process number - element_type: "int" or "float" - ''' - self.seqname = seqname - print(seqname, "sequence type:", type(seq)) - self.process_funcs = [] - self.seq = list(seq) - self.seq_len = seq_len - self.vocab_path = vocab_path - self.vocab_size = int(vocab_size) - - self.bs = bs - self.calc_bn() - print(seqname, "sequence total_length type:", self.N) - - self.sep_tok = sep_tok if sep_tok is not None else "" - self.make_breaker() - self.discard_side = discard_side - if self.seq_len: - self.make_discard() - - if vocab_path: - if (build_vocab is False) and ( - os.path.exists(vocab_path) is False): - print("vocab path not found, building vocab path anyway") - build_vocab = True - if build_vocab: - self.vocab = self.build_vocab(self.seq) - self.vocab.to_json(self.vocab_path) - else: - self.vocab = pd.read_json(self.vocab_path) - self.char2idx, self.idx2char = self.get_mapping(self.vocab) - self.make_translate() - if fixlen: - self.process_batch = self.process_batch_fixlen - self.element_type = element_type - self.make_totorch() - - def __len__(self): - return self.BN - - def calc_bn(self): - """ - calculate batch numbers - :return: batch numbers - """ - self.N = len(self.seq) - self.BN = math.ceil(self.N / self.bs) - return self.BN - - def __getitem__(self, idx): - start_ = self.bs * idx - seq_crop = self.seq[start_:start_ + self.bs] - return self.process_batch(seq_crop) - - def make_breaker(self): - if self.sep_tok != "": - def breaker(self, line): - return str(line).split(self.sep_tok) - else: - def breaker(self, line): - return list(str(line)) - self.breaker = breaker - self.process_funcs.append(self.breaker) - - def make_discard(self): - if self.discard_side == "right": - def discard(self, seqlist): - return seqlist[:self.seq_len] - if self.discard_side == "left": - def discard(self, seqlist): - return seqlist[-self.seq_len:] - self.discard = discard - self.process_funcs.append(self.discard) - - def make_translate(self): - def translate(self, x): - return np.vectorize(self.mapfunc)(x) - - self.translate = translate - self.process_funcs.append(self.translate) - - def make_totorch(self): - if self.element_type == "int": - def totorch(self, seq): - return torch.LongTensor(np.array(seq).astype(np.int)) - if self.element_type == "float": - def totorch(self, seq): - return torch.FloatTensor(np.array(seq).astype(np.float32)) - self.totorch = totorch - self.process_funcs.append(self.totorch) - - def process_batch(self, batch): - return torch.nn.utils.rnn.pad_sequence( - np.vectorize(self.seq2idx, otypes=[list])(batch), batch_first=True) - - def process_batch_fixlen(self, batch): - return torch.nn.utils.rnn.pad_sequence( - np.vectorize( - self.seq2idx, otypes=[list])( - batch+[self.dummy_input()]), batch_first=True)[:-1, ...] - - def dummy_input(self,): - dummy = self.sep_tok.join([" "]*self.seq_len) - return dummy - - def seq2idx(self, x): - for f in self.process_funcs: - x = f(self, x) - return x - - def get_mapping(self, vocab_df): - char2idx = dict(zip(vocab_df["token"], vocab_df["idx"])) - idx2char = dict(zip(vocab_df["idx"], vocab_df["token"])) - return char2idx, idx2char - - def mapfunc(self, x): - """ - from token to index number - """ - try: - return self.char2idx[x] - except: - return 1 - - def get_token_count_dict(self, full_token): - """count the token to a list""" - return Counter(full_token) - - def get_full_token(self, list_of_tokens): - """ - From a list of list of tokens - to a long list of tokens, duplicate tokens included - """ - return self.breaker(self, self.sep_tok.join(list_of_tokens)) - - def build_vocab(self, seq_list): - ct_dict = self.get_token_count_dict(self.get_full_token(seq_list)) - ct_dict["SOS_TOKEN"] = 9e9 - ct_dict["EOS_TOKEN"] = 8e9 - ct_dict[" "] = 7e9 - tk, ct = list(ct_dict.keys()), list(ct_dict.values()) - - token_df = pd.DataFrame({"token": tk, "count": ct}).sort_values( - by="count", ascending=False) - - return token_df.reset_index().drop("index", axis=1)\ - .reset_index()\ - .rename(columns={"index": "idx"}).fillna("")[:self.vocab_size] - - -class fuse(Dataset): def __init__(self, *datasets): """ A pytorch dataset combining the dataset @@ -277,6 +24,9 @@ def __init__(self, *datasets): self.bs = list(bs_s)[0] self.length = list(length_s)[0] + def __repr__(self) -> str: + return f"ZipDataset: {self.datasets}" + def __len__(self): return self.length @@ -288,296 +38,6 @@ def collate(batch): return tuple(i[0] for i in zip(*batch)) -class col_core: - def __init__(self, col_name, save_dir=".matchbox/fields", debug=False): - os.system("mkdir -p %s" % (save_dir)) - self.col_name = col_name - self.debug = debug - self.save_dir = save_dir - if self.save_dir[-1] != "/": - self.save_dir += "/" - - self.meta = dict() - - def save_meta(self): - np.save(self.save_dir + str(self.col_name) + ".npy", self.meta) - - def set_meta(self, meta=None): - """ - pass meta dict values to obj attributes - """ - if meta is None: - meta = self.meta - for k, v in meta.items(): - if self.debug: - print("setting:\t%s\t%s" % (k, v)) - setattr(self, k, v) - - def load_meta(self, path=None): - if path is None: - path = self.save_dir + str(self.col_name) + ".npy" - self.meta = np.load(path).tolist() - self.set_meta(self.meta) - - if self.meta["coltype"] == "tabulate": - self.make_sub() # make sub-objects out of meta - - def make_meta(self): - for attr in self.make_meta_list: - self.meta[attr] = getattr(self, attr) - - def check_dim(self, data): - return pd.DataFrame(data, columns=self.dim_names) - - -class categorical(col_core): - def __init__(self, col_name, save_dir=".matchbox/fields"): - super(categorical, self).__init__(col_name, save_dir) - self.coltype = "categorical" - self.make_meta_list = ["col_name", "coltype", - "idx2cate", "cate2idx", - "width", "eye", "dim_names"] - self.__call__ = self.prepro - - def build(self, pandas_s, max_=20): - assert max_ > 1, "max should be bigger than 1" - - vcount = pd.DataFrame(pandas_s.value_counts()) - - print(vcount) - - self.cate_full = list(vcount.index.tolist()) - self.cate_list = self.cate_full[:max_ - 1] - - # build dictionary - self.idx2cate = dict((k, v) for k, v in enumerate(self.cate_list)) - self.idx2cate.update({len(self.cate_list): "_other"}) - - self.cate2idx = dict((v, k) for k, v in self.idx2cate.items()) - self.eye = np.eye(len(self.cate2idx)) - - self.width = len(self.cate2idx) - - self.dim_names = list("%s -> %s" % (self.col_name, k) - for k in self.cate2idx.keys()) - self.make_meta() - - def trans2idx(self, cate): - """Translate category to index - """ - try: - return self.cate2idx[cate] - except: - return self.cate2idx["_other"] - - def prepro_idx(self, pandas_s): - return pandas_s.apply(self.trans2idx) - - def prepro(self, pandas_s, expand=False): - return self.eye[self.prepro_idx(pandas_s).values.astype(int)] - - def __call__(self, pandas_s, expand=False): - return self.eye[self.prepro_idx(pandas_s).values.astype(int)] - - def dataset(self, df, bs, shuffle): - return DF_Dataset( - df, prepro=self.prepro, bs=bs, shuffle=shuffle, col=self.col_name) - - -class categorical_idx(col_core): - """ - preprocessor - """ - - def __init__(self, col_name, save_dir=".matchbox/fields"): - """ - column name - :param col_name: str,column name - :param save_dir: str, the place to save metadata, - default .matchbox/fields - """ - super(categorical_idx, self).__init__(col_name, save_dir) - self.coltype = "categorical_idx" - self.dim_names = [self.col_name] - self.width = 1 - self.make_meta_list = ["col_name", "coltype", - "idx2cate", "cate2idx", "width", "dim_names"] - self.__call__ = self.prepro - - def build(self, pandas_s, max_=20): - assert max_ > 1, "max should be bigger than 1" - - vcount = pd.DataFrame(pandas_s.value_counts()) - - print(vcount) - - self.cate_full = list(vcount.index.tolist()) - self.cate_list = self.cate_full[:max_ - 1] - - # build dictionary - self.idx2cate = dict((k, v) for k, v in enumerate(self.cate_list)) - self.idx2cate.update({len(self.cate_list): "_other"}) - - self.cate2idx = dict((v, k) for k, v in self.idx2cate.items()) - - self.make_meta() - - def trans2idx(self, cate): - try: - return self.cate2idx[cate] - except: - return self.cate2idx["_other"] - - def prepro(self, pandas_s, expand=True): - x = pandas_s.apply(self.trans2idx).values - if expand: - x = np.expand_dims(x, -1) - return x - - def __call__(self, pandas_s, expand=True): - return self.prepro(pandas_s, expand) - - def dataset(self, df, bs, shuffle): - return DF_Dataset( - df, prepro=self.prepro, bs=bs, shuffle=shuffle, col=self.col_name) - - -class minmax(col_core): - def __init__(self, col_name, fillna=0.0, save_dir=".matchbox/fields"): - """minmax scaler: scale to 0~1""" - super(minmax, self).__init__(col_name, save_dir) - self.coltype = "minmax" - self.fillna = fillna - self.dim_names = [self.col_name] - self.width = 1 - self.make_meta_list = ["col_name", "coltype", - "min_", "max_", "range", "width", "dim_names"] - self.__call__ = self.prepro - - def build(self, pandas_s=None, min_=None, max_=None): - if type(pandas_s) != pd.core.series.Series: - assert (min_ is not None) and ( - max_ is not None),\ - "you have to set min_,max_ value" - self.min_ = min_ - self.max_ = max_ - - else: - pandas_s = pandas_s.fillna(self.fillna) - if min_ == None: - self.min_ = pandas_s.min() - else: - self.min_ = min_ - if max_ == None: - self.max_ = pandas_s.max() - else: - self.max_ = max_ - - self.range = self.max_ - self.min_ - assert self.range != 0, "the value range is 0" - print("min_:%.3f \tmax_:%.3f\t range:%.3f" % - (self.min_, self.max_, self.range)) - self.make_meta() - - def prepro(self, data, expand=True): - x = (np.clip(data.values.astype(np.float64), - self.min_, self.max_) - self.min_) / self.range - if expand: - x = np.expand_dims(x, -1) - return x - - def __call__(self, data, expand=True): - return self.prepro(data, expand) - - def dataset(self, df, bs, shuffle): - return DF_Dataset( - df, prepro=self.prepro, bs=bs, - shuffle=shuffle, col=self.col_name) - - -class tabulate(col_core): - def __init__(self, table_name, save_dir=".matchbox/fields"): - super(tabulate, self).__init__(table_name, save_dir) - self.coltype = "tabulate" - self.cols = dict() - - self.save_dir = save_dir - if self.save_dir[-1] != "/": - self.save_dir = "%s/" % (self.save_dir) - - self.make_meta_list = ["col_name", "coltype", "cols", "dim_names"] - - def build_url(self, metalist): - for url in metalist: - meta_dict = np.load(url).tolist() - self.cols[meta_dict["col_name"]] = meta_dict - self.make_dim() - self.make_meta() - - def build(self, *args): - for obj in args: - self.cols[obj.col_name] = obj.meta - self.make_sub() - self.make_dim() - self.make_meta() - - def make_col(self, meta): - """ - creat sub obj according to sub meta - """ - col_name = meta["col_name"] - - setattr(self, col_name, eval(meta["coltype"])(col_name)) - getattr(self, col_name).set_meta(meta) - if meta["coltype"] == "tabulate": - getattr(self, col_name).make_sub() - getattr(self, col_name).meta = meta - - def make_sub(self): - """ - create sub-objects according to meta - """ - for k, meta in self.cols.items(): - self.make_col(meta) - - def make_dim(self): - self.dim_names = [] - - for k, meta in self.cols.items(): - for sub_dim in meta["dim_names"]: - self.dim_names.append("%s -> %s" % (self.col_name, sub_dim)) - - self.width = len(self.dim_names) - - def prepro(self, data): - """ - data being a pandas dataframe - """ - data_list = [] - - for k, v in self.meta["cols"].items(): - # preprocess the data for every column - col = getattr(self, k) - if v["coltype"] == "tabulate": - data_list.append(col.prepro(data)) - else: - data_list.append(col.prepro(data[k])) - return np.concatenate(data_list, axis=1) - - def __call__(self, data): - return self.prepro(data) - - def dataset(self, df, bs, shuffle): - """ - Get the dataset from the preprocess unit - :param df: dataframe - :param bs: batch size - :param shuffle: if shuffle for the dataset - :return: A pytorch dataset - """ - return DF_Dataset(df, prepro=self.prepro, bs=bs, shuffle=shuffle) - - class test_DS: def __init__(self, dataset, *args, **kwargs): """ @@ -637,7 +97,7 @@ def recover(self, x): return (x * self.std) + self.mean -class historyReplay(object): +class HistoryReplay(object): """ A historic replay scheduler for GAN training diff --git a/forgebox/ftorch/train.py b/forgebox/ftorch/train.py deleted file mode 100644 index da3a790..0000000 --- a/forgebox/ftorch/train.py +++ /dev/null @@ -1,138 +0,0 @@ -from torch.utils.data import DataLoader -from collections import namedtuple -from types import MethodType -import torch -from forgebox.ftorch.optimizer import Opts -from forgebox.ftorch.utils import stty_size - -from forgebox.utils import JUPYTER - -TrainerBatch = namedtuple("TrainerBatch", ("epoch", "i", "data", "trainer")) -from forgebox.train import Trainer as Universal_Trainer -from .cuda import CudaHandler - - -class Trainer(Universal_Trainer): - def __init__(self, dataset, val_dataset=None, batch_size=16, fg=None, - print_on=20, opts = [], batch_start_zg = True, fields=None, is_log=True, shuffle=True, num_workers=4, - conn=None, modelName="model", tryName="try", callbacks=[], val_callbacks=[], jupyter = JUPYTER, using_gpu = True): - """ - Pytorch trainer - fields: the fields you choose to print out - is_log: writing a log? - - Training: - - write action function for a step of training, - assuming a generator will spit out tuple x,y,z in each: - then pass the function to object - - t=Trainer(...) - t.train(epochs = 30) - - @t.step_train - def action(self): - x,y,z = self.data - - self.opt.sgd.zero_grad() - self.opt.adam.zero_grad() - - # model is a global variable, or many models if you like - y_ = model(x) - y2_ = model_2(z) - - ...... more param updating details here - - # metrics you want to check return as dictionary here - return {"loss":loss.item(),"acc":accuracy.item()} - - same work for validation:trainer.val_action = val_action - train_data: torch.utils.data.dataset.Dataset - val_data: torch.utils.data.dataset.Dataset - print_on: int, print metrics on progress for each n steps, default 20 - batch_size: int, default 16 - batch_start_zg: bool, zero grad all the optimizers at start, default True - - conn: a sql table connection, (sqlalchemy). if assigned value, save the record in the designated sql database; - """ - self.batch_size = batch_size - self.shuffle = shuffle - self.num_workers = num_workers - train_data = self.ds_to_dl(dataset) - val = (len(val_dataset)>0) - val_data = self.ds_to_dl(val_dataset) if val else None - train_len = len(train_data) - val_len = len(val_data) if val else None - self.before_train_batch_list = [] - self.before_val_batch_list = [] - super().__init__(train_data, train_len=train_len, val_data=val_data, val_len=val_len, - fg=fg, print_on=print_on, fields=fields,batch_start_zg = batch_start_zg, - is_log=is_log, conn=conn, modelName=modelName, - tryName=tryName, callbacks=callbacks, val_callbacks=val_callbacks, - jupyter = jupyter - ) - self.initialize_gpu(using_gpu) - self.initialize_opt(opts) - - def ds_to_dl(self,ds): - return DataLoader(ds, batch_size=self.batch_size, shuffle=self.shuffle, num_workers=self.num_workers) - - def val_action_wrap(self): - with torch.no_grad(): - return self.val_action() - - def before_train_batch(self, func_name): - """ - @t.before_train_batch("process_data1") - def pd1(self): - .... - """ - def wrapper(f): - setattr(self,func_name, MethodType(f, self)) - self.before_train_batch_list.append(getattr(self,func_name)) - return wrapper - - def before_val_batch(self, func_name): - """ - @t.before_val_batch("process_data1") - def pd1(self): - .... - """ - def wrapper(f): - setattr(self, func_name, MethodType(f, self)) - self.before_val_batch_list.append(getattr(self,func_name)) - return wrapper - - def data_to_dev(self,device ="cuda:0"): - def to_dev(self): - self.data = tuple(dt.to(device) for dt in self.data) - self.step_extra("data_to_device")(to_dev) - self.step_extra("val_data_to_device")(to_dev) - - def initialize_opt(self,opts): - if type(opts)==list: - self.opt = Opts(*opts) - if len(opts) == 0: - print(self.warning_no_optimizer) - elif type(opts) == dict: - self.opt = Opts(**opts) - else: - self.opt = Opts(opts) - - def initialize_gpu(self,using_gpu): - """ - decide whether to use cuda device - """ - self.using_gpu = False - if (using_gpu == True) and (torch.cuda.is_available()): - self.using_gpu = True - if self.using_gpu: - self.data_to_dev() - - @property - def warning_no_optimizer(self): - return f"""{stty_size()*"="}\nNotice, The Trainer was not initiated with optimizer - Use the following syntax to initialize optimizer - t.opt["adm1"] = torch.optim.Adam(m1.parameters()) - t.opt["adg1"] = torch.optim.Adagrad(m2.parameters())\n{stty_size()*"="} - """ diff --git a/forgebox/ftorch/utils.py b/forgebox/ftorch/utils.py deleted file mode 100644 index 68bcb14..0000000 --- a/forgebox/ftorch/utils.py +++ /dev/null @@ -1,31 +0,0 @@ -from forgebox.utils import JUPYTER -if JUPYTER: - from IPython.display import display -import torch -import os - - -def mars(printstuff): - """ - A print function works between jupyter and console print - :param printstuff: - """ - if JUPYTER: - display(printstuff) - else: - print(printstuff) - - -def save_model(model, path): - torch.save(model.state_dict(), path) - - -def load_model(model, path): - model.load_state_dict(torch.load(path)) - - -def stty_size(): - try: - return int(os.popen('stty size', 'r').read().split()[1]) - except: - return 60 diff --git a/forgebox/hf/__init__.py b/forgebox/hf/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/forgebox/hf/data.py b/forgebox/hf/data.py deleted file mode 100644 index dfe8367..0000000 --- a/forgebox/hf/data.py +++ /dev/null @@ -1,217 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/70_hf_transformer_data.ipynb (unless otherwise specified). - -__all__ = ['convert_iob2_file_to_iobes', 'conbine_iobes_file', 'IOBES'] - -# Cell -from ..imports import * -from ..category import Category -from typing import List, Dict, Callable, Any, Tuple - -# Cell -def convert_iob2_file_to_iobes(file_path, result_path): - """ - Convert IOB2 file to IOBES - """ - with open(file_path, 'r') as f: - lines = f.readlines() - with open(result_path, 'w') as f: - for line in lines: - line = line.strip() - if line == '': - f.write('\n') - continue - line = line.split() - if line[-1] == 'O': - f.write(' '.join(line) + '\n') - else: - f.write(' '.join(line[:-1]) + ' ' + line[-1] + '\n') - - -def conbine_iobes_file( - file_paths: List[Path], - new_file_path: Path -): - """ - Conbine from multiple IOBES files - into IOBES files - """ - with open(new_file_path, 'w') as new_file: - for file_path in file_paths: - with open(file_path, 'r') as file: - for line in file: - new_file.write(line) - -# Cell -class IOBES(Dataset): - """ - Load iobes file for NER training task - """ - - def __init__( - self, - file_path, - tokenizer, - max_len=128, - save_buffer: int = 15, - category: Category = None, - return_string: bool = False, - use_frag: bool = False, - ): - """ - file_path, - tokenizer, - max_len=128, - save_buffer: int = 15, - category: Category = None, - label categories, if set to None, will be figured out - automatically. - You can set this to None for train dataset, but for valid - dataset: - valid_ds = IOBES(...,category=train_ds.cates) - return_string: bool = False, do we return original string - for tokenizer output, this option is good for debuging - but the data won't pass into cuda if choose so - use_frag: bool = False, do we use prepend like 'I-','B-' - """ - self.file_path = file_path - self.max_len = max_len - self.pairs = [] - self.list_of_words = [] - self.list_of_labels = [] - self.tokenizer = tokenizer - self.cates = category - self.return_string = return_string - self.use_frag = use_frag - self.load_data(save_buffer) - - def load_data(self, save_buffer: int = 15): - """ - Load file in to object structure - """ - with open(self.file_path, 'r') as f: - for line in f: - line = line.strip() - if line: - splited = line.split() - if len(splited) != 2: - continue - word, label = splited - # do we use 'I-', 'B-' etc - if self.use_frag is False: - if "-" in label: - label = label.split('-')[1] - self.pairs.append([word, label]) - - self.pairs = np.array(self.pairs) - - if self.cates is None: - labels_df = pd.DataFrame({"label": self.pairs[:, 1]}) - self.cates = Category(list(labels_df.vc("label").index)) - - self.batching_words(save_buffer) - - def batching_words(self, save_buffer: int = 15): - """ - batching self.words into self.list_of_words - by self.max_len -15 - """ - for i in range(0, len(self.pairs), self.max_len-save_buffer): - chunk_slice = slice(i, i+self.max_len-save_buffer) - self.list_of_words.append(self.pairs[chunk_slice, 0]) - self.list_of_labels.append(self.pairs[chunk_slice, 1]) - - def __len__(self) -> int: - return len(self.list_of_words) - - def __getitem__(self, idx: int) -> Tuple[List[str]]: - return list(self.list_of_words[idx]), list(self.list_of_labels[idx]) - - def __repr__(self): - return f"""NER dataset using IOBES annotation - {len(self)} sentences, - Labels: - {list(self.cates.i2c)} - """ - - def collate_fn(self, data): - """ - data: list of tuple - """ - words, text_labels = zip(*data) - - inputs = self.tokenizer( - list(words), - return_tensors='pt', - padding=True, - truncation=True, - max_length=self.max_len, - is_split_into_words=True, - return_offsets_mapping=True, - add_special_tokens=False, - ) - return self.align_offsets(inputs, text_labels, words) - - def align_offsets( - self, - inputs, - text_labels: List[List[str]], - words: List[List[str]] - ): - """ - inputs: output if tokenizer - text_labels: labels in form of list of list of strings - words: words in form of list of list of strings - """ - labels = torch.zeros_like(inputs.input_ids).long() - labels -= 100 - text_lables_array = np.empty(labels.shape, dtype=object) - words_array = np.empty(labels.shape, dtype=object) - max_len = inputs.input_ids.shape[1] - - for row_id, input_ids in enumerate(inputs.input_ids): - word_pos = inputs.word_ids(row_id) - for idx, pos in enumerate(word_pos): - if pos is None: - continue - if pos <= max_len: - labels[row_id, idx] = self.cates.c2i[text_labels[row_id][pos]] - if self.return_string: - text_lables_array[row_id, - idx] = text_labels[row_id][pos] - words_array[row_id, idx] = words[row_id][pos] - - inputs['labels'] = labels - if self.return_string: - inputs['text_labels'] = text_lables_array.tolist() - inputs['word'] = words_array.tolist() - return inputs - - def dataloader(self, batch_size: int = 32, shuffle: bool = True): - """ - Create dataloader - """ - return DataLoader( - self, - batch_size=batch_size, - shuffle=shuffle, - collate_fn=self.collate_fn, - ) - - def one_batch(self, batch_size: int = 32, shuffle: bool = True): - return next(iter(self.dataloader(batch_size, shuffle))) - - def visualize_batch(self, batch, row_idx=0): - return list(zip(self.tokenizer.convert_ids_to_tokens(batch.input_ids[row_idx]), - batch.labels[row_idx].numpy(), - batch.text_labels[row_idx], - batch.word[row_idx], - batch.offset_mapping[row_idx].numpy(), - )) - - def set_hfconfig(self, config): - """ - set the category information to huggingface config - """ - config.num_labels = len(self.cates) - config.id2label = {i: label for i, label in enumerate(self.cates.i2c)} - config.label2id = {label: i for i, label in enumerate(self.cates.i2c)} \ No newline at end of file diff --git a/forgebox/hf/train.py b/forgebox/hf/train.py deleted file mode 100644 index e797c5b..0000000 --- a/forgebox/hf/train.py +++ /dev/null @@ -1,326 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/72_pl_training.ipynb (unless otherwise specified). - -__all__ = ['ner_model_from', 'ner_tokenizer_from', 'NERDataModule', 'NERModule', 'clean_ner_output', 'NERInference'] - -# Cell -from .data import IOBES -from ..imports import * -from ..loop import chunkify -import pytorch_lightning as pl -from transformers import ( - AutoModelForTokenClassification, - AutoTokenizer, - pipeline -) -from tqdm.notebook import tqdm -from typing import Callable, List -from torch import device - -# Cell -try: - ishell = get_ipython() - IS_JUPYTER = True - from tqdm.notebook import tqdm -except NameError: - IS_JUPYTER = False - from tqdm import tqdm - -# Cell - -# ner model and tokenizer -def ner_model_from( - name:str, dataset: IOBES -): - """ - name: from_pretrain(name) - """ - model = AutoModelForTokenClassification.from_pretrained( - name, - num_labels=len(dataset.cates), - ) - dataset.set_hfconfig(model.config) - return model - -def ner_tokenizer_from( - name: str -): - return AutoTokenizer.from_pretrained( - name, add_prefix_space=True) - -# Cell - -# ner data module -class NERDataModule(pl.LightningDataModule): - def __init__(self, train_ds, val_ds, batch_size=32): - super().__init__() - self.train_ds = train_ds - self.val_ds = val_ds - self.batch_size = batch_size - - def train_dataloader(self): - return self.train_ds.dataloader(batch_size=self.batch_size, shuffle=True) - - def val_dataloader(self): - return self.val_ds.dataloader(batch_size=self.batch_size*2, shuffle=False) - -# Cell - -# ner module -class NERModule(pl.LightningModule): - """ - PyTorch lightning module for training ner model - """ - def __init__( - self, model, - ): - """ - model: huggingface transformer model for ner - """ - super().__init__() - self.model = model - - def forward(self, batch): - return self.model( - input_ids=batch['input_ids'], - attention_mask=batch['attention_mask'], - labels=batch['labels']) - - def training_step(self, batch, batch_idx): - outputs = self(batch) - loss = outputs.loss - self.log("loss", loss) - self.log("acc", self.calcualte_acc(outputs, batch.labels)) - return loss - - def validation_step(self, batch, batch_idx): - outputs = self(batch) - loss = outputs.loss - self.log("val_loss", loss) - self.log("val_acc", self.calcualte_acc(outputs, batch.labels)) - return loss - - def calcualte_acc(self, outputs, labels): - pred_idx = outputs.logits.argmax(-1) - mask = torch.ones_like(pred_idx) - mask[labels==-100]=False - return (pred_idx[mask]==labels[mask]).float().mean() - - def configure_optimizers(self): - # discriminative learning rate - param_groups = [ - {'params': self.model.roberta.parameters(), 'lr': 5e-6}, - {'params': self.model.classifier.parameters(), 'lr': 1e-3}, - ] - optimizer = torch.optim.Adam(param_groups, lr=1e-3) - return optimizer - -# Cell -def clean_ner_output(self, outputs): - """ - Cleaning output for NER task - """ - results = [] - current = [] - last_idx = 0 - # make to sub group by position - for output in outputs: - if output["start"] in [last_idx, last_idx-1]: - current.append(output) - else: - results.append(current) - current = [output, ] - last_idx = output["end"] - if len(current) > 0: - results.append(current) - - # from tokens to string - strings = [] - for c in results: - tokens = [] - starts = [] - ends = [] - for o in c: - tokens.append(o['word']) - starts.append(o['start']) - ends.append(o['end']) - - new_str = self.tokenizer.convert_tokens_to_string(tokens) - if new_str != '': - strings.append(dict( - word=new_str, - start=min(starts), - end=max(ends), - entity=c[0]['entity_group'] - )) - return strings - -# Cell -class NERInference: - """ - NER Inference pipeline - ner = NERInference.from_pretrained('xxxx/xxxx') - ner.predict(['text1','text2']) - """ - - def __init__(self, model, tokenizer, name=None): - super().__init__() - self.model = model.eval() - self.tokenizer = tokenizer - self.name = name if name else "NER model" - - def __repr__(self): - return f"[NERInference on {self.name}]" - - def to(self, device_str): - self.model = self.model.to(device(device_str)) - return self - - @classmethod - def from_pretrained(cls, tag): - """ - Load from pretrained model and tokenizer - """ - model = AutoModelForTokenClassification.from_pretrained(tag) - tokenizer = AutoTokenizer.from_pretrained(tag) - return cls(model=model, tokenizer=tokenizer, name=model.config._name_or_path) - - def __call__(self, data, batch_size=32, dev=device("cpu")): - if type(data) == str: - return self.batch_predict([data,]) - else: - return self.predict(data, dev=dev, batch_size=batch_size) - - def predict( - self, - texts: List[str], - dev=device("cpu"), - batch_size: int = 32, - progress_bar: bool = True - ) -> pd.DataFrame: - """ - Predict a list of sentences/ paragraphs - """ - # place the model into device - self.model = self.model.to(dev) - iterator = list(enumerate(chunkify(texts, bs=batch_size))) - if progress_bar: - iterator = tqdm(iterator, leave=False) - - # run through iterator - all_dfs = [] - for i, text_b in iterator: - # by batch prediction - batch_df = self.batch_predict(text_b) - if len(batch_df) > 0: - # calculate the row number - batch_df['text_id'] = batch_df.apply( - lambda row: i*batch_size+row.batch_row_sn, axis=1) - all_dfs.append(batch_df) - - # place the model back to cpu - self.model = self.model.to("cpu") - return pd.concat(all_dfs).reset_index(drop=True) - - def tokenizing(self, texts): - inputs = self.tokenizer( - texts, - padding="max_length", - max_length=self.tokenizer.model_max_length, - return_attention_mask=True, - return_tensors='pt', truncation=True, return_offsets_mapping=True - ).to(self.model.device) - return inputs - - - def batch_predict(self, texts:List[str])-> pd.DataFrame: - """ - Predict a single batch of sentences - """ - id2label = self.model.config.id2label - inputs = self.tokenizing(texts) - - with torch.no_grad(): - outputs = self.model(input_ids=inputs.input_ids, - attention_mask=inputs.attention_mask) - inputs = inputs.to(device('cpu')) - - pred_idx = outputs.logits.argmax(-1).to(device("cpu")) - batch_size = pred_idx.size(0) - offsets = inputs.offset_mapping - results = [] - for bi in range(batch_size): - text = texts[bi] - input_ids = inputs.input_ids[bi] - word_ids = inputs.word_ids(bi) - pred_ids = pred_idx[bi] - # initial values for the row - last_pos = 0 - previous_has_positive = False - current_start = 0 - current_index = 0 - current_id = 0 - line = [] - for ti in range(1, len(input_ids)): - if input_ids[ti] == self.tokenizer.sep_token_id: - break - # is the current token an appending sub-word? - if word_ids[ti] == last_pos: - pass - # is current token negative - elif pred_ids[ti].item() == 0: - # store the previous hanging prediction - if previous_has_positive: - start = current_start - end = offsets[bi, ti, 0].item() - line.append({ - "start": start, "end": end, - "entity": id2label[current_id], - "word": text[start:end], - "index": current_index, - }) - - current_start = offsets[bi, ti, 0].item() - previous_has_positive = False - current_id = 0 - current_index = ti - # has positive prediction index, other than zero - else: - if previous_has_positive: - # different than the previous - if current_id != pred_ids[ti].item(): - start = current_start - end = offsets[bi, ti, 0].item() - line.append({ - "start": start, - "end": end, - "entity": id2label[current_id], - "word": text[start:end], - "index": current_index, - }) - current_start = offsets[bi, ti, 0].item() - # this is the 1st postive predict for a while - else: - current_start = offsets[bi, ti, 0].item() - previous_has_positive = True - current_index = ti - current_id = pred_ids[ti].item() - - last_pos = word_ids[ti] - if previous_has_positive: - start = current_start - end = offsets[bi, ti, 1].item() - line.append({ - "start": start, - "end": end, - "entity": id2label[current_id], - "word": text[start:end], - "index": current_index, - }) - - results.append(line) - all_dfs = [] - for i, res in enumerate(results): - sub_df = pd.DataFrame(res) - sub_df["batch_row_sn"] = i - all_dfs.append(sub_df) - return pd.concat(all_dfs) \ No newline at end of file diff --git a/forgebox/html.py b/forgebox/html.py index 80d090d..762ba8a 100644 --- a/forgebox/html.py +++ b/forgebox/html.py @@ -1,46 +1,69 @@ # AUTOGENERATED! DO NOT EDIT! File to edit: nbs/04_html.ipynb (unless otherwise specified). -__all__ = ['DOM', 'image_to_base64', 'data_url', 'img_dom', 'deeper', 'list_group', 'col_sm', 'list_group_kv', 'JS', +import math +from PIL.Image import Image as ImageClass +import base64 +from io import BytesIO +__all__ = ['display', 'DOM', 'image_to_base64', 'data_url', + 'img_dom', 'deeper', 'list_group', + 'col_sm', 'list_group_kv', 'JS', 'JS_file'] # Cell from IPython.display import HTML +from typing import Dict, Any + +try: + display(HTML('''''')) +except: + display = print + class DOM: - def __init__(self,txt,tag,kwargs = dict()): + """ + DOM object in python + dom = DOM("some text", "div", {"class":"myclass"}) + dom.append(another_dom) + dom['class'] = "newclass" + # show in jupyter + dom() + """ + + def __init__(self, txt, tag, kwargs=dict()): self.txt = txt self.tag = str(tag).lower() self.attrs = kwargs self.refresh_attr() @staticmethod - def extend(text,tag,**kwargs): - attributes =(" ".join(f'{k}="{v}"' for k,v in kwargs.items())) - attributes=" "+attributes if attributes else attributes + def extend(text, tag, **kwargs): + attributes = (" ".join(f'{k}="{v}"' for k, v in kwargs.items())) + attributes = " "+attributes if attributes else attributes start = f"<{tag}{attributes}>" inner = f"{text}" end = f"" text = f"{start}{inner}{end}" - return start,inner,end + return start, inner, end def refresh_attr(self): - self.start,self.inner,self.end = self.extend(self.txt,self.tag,**self.attrs) + self.start, self.inner, self.end = self.extend( + self.txt, self.tag, **self.attrs) - def __mul__(self,new_tag): - assert type(new_tag)==str - return DOM(self.text,new_tag) + def __mul__(self, new_tag): + assert type(new_tag) == str + return DOM(self.text, new_tag) - def __add__(self,dom): + def __add__(self, dom): return self.text+dom.text def __repr__(self): return f"{self.start}{self.inner}{self.end}" - def __getitem__(self,k): + def __getitem__(self, k): return self.attrs[k] - def __setitem__(self,k,v): - self.update({k,v}) + def __setitem__(self, k, v): + self.update({k, v}) def __call__(self): self.display() @@ -49,22 +72,21 @@ def __call__(self): def text(self): return str(self) - def append(self,subdom): + def append(self, subdom): self.inner = self.inner+str(subdom) return self - def update(self,dict_): + def update(self, dict_): self.attrs.update(dict_) self.refresh_attr() return self def display(self): + """ + Display the html in Jupyter + """ display(HTML(self.text)) -# Cell -from io import BytesIO -import base64 -from PIL.Image import Image as ImageClass def image_to_base64( img: ImageClass @@ -81,6 +103,7 @@ def image_to_base64( base64_str = base64.b64encode(byte_data) return base64_str.decode() + def data_url( img: ImageClass ) -> str: @@ -91,10 +114,13 @@ def data_url( """ return f"data:image/jpg;base64,{image_to_base64(img)}" -def img_dom(img: ImageClass): - return DOM("","img",{"src":data_url(img)}) -# Cell +def img_dom(img: ImageClass) -> DOM: + """ + show PIL.Image in HTML + """ + return DOM("", "img", {"src": data_url(img)}) + def deeper(x): if type(x) in [list, set, tuple]: @@ -115,9 +141,6 @@ def list_group(iterable): ul.append(li) return ul -# Cell -import math - def col_sm(iterable, portions=None,): if portions == None: @@ -127,23 +150,27 @@ def col_sm(iterable, portions=None,): row.append(DOM(i, "div", {"class": f"col-sm-{p}"})) return row -# Cell -def list_group_kv(data): + +def list_group_kv(data: Dict[str, Any]) -> DOM: + """ + Key + """ result = [] - for k,v in data.items(): - row = DOM("","div",{"class":"row"}) - row.append(DOM(f"{k}","strong",{"class":"col-sm-5"}))\ - .append(DOM(f"{deeper(v)}","span",{"class":"col-sm-7"})) + for k, v in data.items(): + row = DOM("", "div", {"class": "row"}) + row.append(DOM(f"{k}", "strong", {"class": "col-sm-5"}))\ + .append(DOM(f"{deeper(v)}", "span", {"class": "col-sm-7"})) result.append(row) return list_group(result) -# Cell + def JS(code): - DOM(code,"script",)() + DOM(code, "script",)() + def JS_file(path): """ load javascript file """ - with open(path,"r") as f: - DOM(f.read(),"script")() \ No newline at end of file + with open(path, "r") as f: + DOM(f.read(), "script")() diff --git a/forgebox/images/widgets.py b/forgebox/images/widgets.py index fd611a0..aa899b3 100644 --- a/forgebox/images/widgets.py +++ b/forgebox/images/widgets.py @@ -1,17 +1,9 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/51_image_widgets.ipynb (unless otherwise specified). - -__all__ = ['image_dom', 'with_title_dom', 'view_images', 'Subplots'] - -# Cell -import base64 -from io import BytesIO from PIL import Image from typing import List, Callable import math -from ..html import DOM, image_to_base64, data_url +from forgebox.html import data_url, DOM -# Cell def image_dom( img: Image, **kwargs @@ -21,7 +13,6 @@ def image_dom( with PIL.Image object return forgebox.html.DOM """ - from ..html import DOM img_dom = DOM("", "img", dict( src=data_url(img), @@ -32,18 +23,18 @@ def image_dom( return div_dom -def with_title_dom(img: Image, title:str, col: int): +def with_title_dom(img: Image, title: str, col: int): from ..html import DOM img_dom = image_dom(img) - out_dom = DOM(img_dom, "div", {"class":f"col-sm-{col}"}) + out_dom = DOM(img_dom, "div", {"class": f"col-sm-{col}"}) out_dom.append(title) return out_dom def view_images( *images, - num_per_row: int=4, - titles: List=None, + num_per_row: int = 4, + titles: List = None, ): """ Create
    wraping up images @@ -69,7 +60,7 @@ def view_images( frame.append(with_title_dom(img, title, col)) return frame -# Cell + class Subplots: """ Simplifying plt sublots @@ -115,4 +106,4 @@ def __call__(self, *args, **kwargs): ax = self.ax[math.floor( float(self.i)/float(self.ncol)), self.i % self.ncol] self.single_func(ax, *args, **kwargs) - self.i += 1 \ No newline at end of file + self.i += 1 diff --git a/forgebox/imports.py b/forgebox/imports.py index a460cfd..1f5a9cb 100644 --- a/forgebox/imports.py +++ b/forgebox/imports.py @@ -4,11 +4,11 @@ # Cell -__all__ = ["pd","np","partial","Path","json","Counter", - "plt","os","sys","glob","Image",] +__all__ = ["pd", "np", "partial", "Path", "json", "Counter", + "plt", "os", "sys", "glob", "Image", ] # import enhanced version of pandas -from .pdenhanced import pd +from .pd_plus import pd import numpy as np from pathlib import Path import json @@ -25,7 +25,7 @@ pass try: - from .widgets import search_box,paginate + from .widgets import search_box, paginate pd.DataFrame.search_box = search_box pd.DataFrame.paginate = paginate except: @@ -36,66 +36,18 @@ from torch import nn from torch.utils.data.dataset import Dataset from torch.utils.data.dataloader import DataLoader - __all__+=["nn","torch","Dataset","DataLoader"] + __all__ += ["nn", "torch", "Dataset", "DataLoader"] except: pass try: from ipywidgets import interact, interact_manual from IPython.display import HTML - __all__+=["interact","interact_manual","HTML"] -except: - pass - -try: - import redis - def read_redis(key, host='localhost', port=6379, db=3): - rd = redis.Redis(host=host, port=port, db=db) - return pd.read_json(rd.get(key)) - - __all__+=["read_redis",] - - def to_redis(self, key:str, con:redis.Redis = None, ex:int=600): - """ - Save dataframe to redis - """ - if con is None: - con = redis.Redis(host='localhost', port=6379, db=3) - return con.set(key, self.to_json()) - - pd.DataFrame.to_redis = to_redis - - def df_cache(ex=600, host='localhost', port=6379, db=3): - """ - Caching pd.DataFrame, use as decorator - - @df_cache(ex=300) - def get_table_abc(uuid): - return pd.read_sql(f"select * from abc where uuid='{uuid}'", con=conn) - - within 5 minutes, under same uuid, the code will query data base only once - """ - rd = redis.Redis(host=host, port=port, db=db) - def decorator(f): - def wrapper(*args, **kwargs): - key = "_".join(str(i).lower() for i in args) - if len(kwargs)>0: - key += "_" - key += "_".join(f"{k}-{v}" for k,v in kwargs.items()) - if rd.exists(key): - return pd.read_json(rd.get(key)) - df = f(*args, **kwargs) - df.to_redis(key, con=rd) - return df - - return wrapper - return decorator - __all__+=["df_cache",] - + __all__ += ["interact", "interact_manual", "HTML"] except: pass from glob import glob from PIL import Image -Path.ls = lambda x:os.listdir(x) \ No newline at end of file +Path.ls = lambda x: os.listdir(x) diff --git a/forgebox/initialize.py b/forgebox/initialize.py deleted file mode 100644 index afa5e62..0000000 --- a/forgebox/initialize.py +++ /dev/null @@ -1,9 +0,0 @@ -from forge.config import SQLALCHEMY_DATABASE_URI -from configparser import ConfigParser - -config = ConfigParser() - -config["DATABASE"] = {"fg_db":SQLALCHEMY_DATABASE_URI} - -with open('/etc/forgebox.cfg', 'w') as configfile: - config.write(configfile) \ No newline at end of file diff --git a/forgebox/loop.py b/forgebox/loop.py deleted file mode 100644 index df8ca78..0000000 --- a/forgebox/loop.py +++ /dev/null @@ -1,622 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/10_loop.ipynb (unless otherwise specified). - -__all__ = ['Stuff', 'method4all', 'StorageCore', 'Loop', 'ProgressBar', 'error_tolerate', 'Tolerate', 'LambdaCall', - 'Event', 'chunkify'] - -# Cell -import numpy as np -import pandas as pd -import math - -# Cell -class Stuff: - _is_stuff = True - def __init__(self,name): - self.name = name - self.cases = dict() - self.funcs = dict() - - def __setitem__(self,k,v): - setattr(self,k,v) - - def __setattr__(self,k,v): - if k not in ["name","cases","funcs"]: - self.cases[k] = v - else: - super().__setattr__(k,v) - - def __getitem__(self,k): - return self.cases[k] - - def append(self,obj): - self[f"{self.name}_{len(self+1)}"] = obj - - def clear(self): - self.cases = dict() - - def __getattr__(self,k): - if k in self.cases: - return self.cases[k] - elif k in self.funcs: - return self.funcs[k] - else: - return super().__getattr__() - - def __repr__(self,): - return f"🍄:{self.name}[\n\t"+"\n\t".join(self.cases.keys())+"\n]" - - def __len__(self): - return len(self.cases) - - def apply(self,func,scope = None): - """ - func, the function to apply on each element - scope, list, name the scope of element - """ - def apply_func(*args,**kwargs): - for k,case in self.cases.items(): - if scope!=None: - if k not in scope: - continue - if type(func)==str: - self[k] = getattr(case,func)(*args,**kwargs) - else: - self[k] = func(case,*args,**kwargs) - return apply_func - - def update(self,dictionary): - for k, v in dictionary.items(): - self[k]=v - - def __call__(self,func=None): - """ - func: str or callable, - if str, it will run on each subject case's such named function - if callable, it will call on the callable, with the 1st arg being the subject case - args: extra args - kwargs: extra key word arguments - - return: a list of returned results - """ - def run_funcs(*args,**kwargs): - results = dict() - for k,case in self.cases.items(): - if type(func)==str: - results.update({k:getattr(case,func)(*args,**kwargs)}) - elif func==None: - results.update({k:getattr(case,"__call__")(*args,**kwargs)}) - else: - results.update({k:func(case,*args,**kwargs)}) - return results - return run_funcs - -# Cell -from tqdm import tqdm -from types import MethodType -import inspect -from functools import partial - -def method4all(f): - """ - Use this function as a decorator, - The decorated function under Loop class can be used on outer layer - """ - setattr(f,"forall",True) - return f - -class StorageCore: - def __init__(self,start_layer): - self.layers = [] - self.lmap = dict() - self.forall_pool = dict() - self.new_layer(start_layer) - self.i = -1 - self.epoch = -1 - - def new_layer(self,layer): - layer.core = self - self.layers.append(layer) - - self.lmap[layer._loop_layer]=layer - if hasattr(self,layer.name): - raise KeyError(f"Layer name already exist: {layer.name}") - setattr(self,layer.name,layer) - self.update_forall(layer) - self.assign_forall(layer) - - def __repr__(self): - return str(self.lmap) - - def for_all_functions(self,obj): - return dict(inspect.getmembers(obj, - predicate=lambda x:hasattr(x,"forall"))) - - def update_forall(self,obj): - self.forall_pool.update(self.for_all_functions(obj)) - - def assign_forall(self,obj): - for name,f in self.forall_pool.items(): - setattr(obj,name,f) - -class Loop(list): - """ - Basic loop class - """ - _loop_layer = 0. - _loop_obj = True - def __init__(self,iterable = [],name=None): - self.iterable = iterable - self.next_layer = None - self.name = name if name!=None else self.__class__.__name__ - - if hasattr(iterable,"_loop_layer"): - self._loop_layer = iterable._loop_layer + 1 - iterable.next_layer = self - iterable.core.new_layer(self) - else: - self.core = StorageCore(self) - - def __call__(self): - pass - - def __repr__(self): - return f"layer🍰{self.name}" - - def on(self,iterable): - self.iterable = iterable - self._loop_layer = iterable._loop_layer + 1 - - def func_detail(self,f): - detail = dict({"🐍func_name":f.__name__, - "⛰doc":f.__doc__, - "😝var":",".join(f.__code__.co_varnames), - "😜names":",".join(f.__code__.co_names), - }) - return detail - - def func_detail_df(self): - funcs = [] - result = [] - for idx,layer in self.core.lmap.items(): - for fname,f in self.core.for_all_functions(layer).items(): - if id(f) not in funcs: - dt = self.func_detail(f) - dt.update(layer=str(layer)) - result.append(dt) - funcs.append(id(f)) - return pd.DataFrame(result) - - def search(self): - from .widgets import search_box - pd.set_option('display.max_colwidth', 0) - doc_df = self.func_detail_df() - doc_df["⛰doc"]= doc_df["⛰doc"].apply(lambda x:str(x).replace("\n"," ")) - search_box(doc_df, ["🐍func_name","⛰doc","layer","😝var","😜names"]) - - def summary(self): - rt = f"Loop layer {self.name} summary:\n" - rt+= "="*50+"\n" - funcs = [] - for idx,layer in self.core.lmap.items(): - rt+= f"🍰layer{idx}\t{str(layer)}\n" - for fname,f in self.core.for_all_functions(layer).items(): - if id(f) not in funcs: - rt+="\t" - rt+="\n\t".join(f"[{k}]\t{v}" for k,v in self.func_detail(f).items()) - rt+="\n\t"+"."*35+"\n" - funcs.append(id(f)) - rt+="-"*50+"\n" - rt+= "="*50+"\n" - print(rt) - - def __len__(self): - return self.iterable.__len__() - - def run(self,run_nb=1): - """ - Run through iteration - run start_call for every layer on the start of iteration - run __call__ for every layer for each iteration - run end_call for every layer on the end of iteration - """ - self.before_1st_callon() - for i in range(run_nb): - self.one_epoch() - self.after_last_callon() - - def one_epoch(self): - first = self.layers[0] - self.refresh_i() - first.start_callon() - for element in first: - first() - first.end_callon() - - def __getitem__(self,idx): - return self.iterable[idx] - - def __setitem__(self,idx,v): - self.iterable[idx] = v - - def refresh_i(self): - self.core.i=-1 - self.core.epoch+=1 - - def update_i(self): - self.core.i+=1 - - def downstream_wrap(self,f):return f() - def downstream_start_wrap(self,f):return f() - def downstream_end_wrap(self,f):return f() - def downstream_before_1st_wrap(self,f): return f() - def downstream_after_last_wrap(self,f): return f() - - def downstream(self,f): - """ - set downstream wrapper on callback, - The callback will happend in the local realm of the deocrated function - example - @loop.downstream - def control_layer(self,callback): - try: - callback() - except: - print("error happened") - """ - setattr(self,"downstream_wrap",MethodType(f,self)) - return f - - def downstream_start(self,f): - """ - set downstream wrapper on start callback, - The start_callback will happend in the local realm of the deocrated function - example - @loop.downstream_start - def control_layer(self,start_callback): - try: - start_callback() - except: - print("error happened") - """ - setattr(self,"downstream_start_wrap",MethodType(f,self)) - return f - - def downstream_end(self,f): - """ - set downstream wrapper on end callback, - The end_callback will happend in the local realm of the deocrated function - @loop.downstream_end - def control_layer(self,end_callback): - try: - end_callback() - except: - print("error happened") - """ - setattr(self,"downstream_end_wrap",MethodType(f,self)) - return f - - def callon(self): - self() - self.downstream_wrap(self.iter_cb) - - def start_callon(self): - self.start_call() - self.downstream_start_wrap(self.start_cb) - - def end_callon(self): - self.end_call() - self.downstream_end_wrap(self.end_cb) - - def before_1st_callon(self): - self.before_1st_call() - self.downstream_before_1st_wrap(self.before_1st_cb) - - def after_last_callon(self): - self.after_last_call() - self.downstream_before_1st_wrap(self.after_last_cb) - - def iter_cb(self): - """ - call back during each iteration - """ - if self.next_layer!=None: - self.next_layer.callon() - self.after() - - def after(self): - pass - - def start_cb(self): - """ - callback at the start of iteration - """ - if self.next_layer!=None: - self.next_layer.start_callon() - - def end_cb(self): - """ - callback at the end of iteration - """ - if self.next_layer!=None: - self.next_layer.end_callon() - - def before_1st_cb(self): - """ - callback before the 1st of iteration - """ - if self.next_layer!=None: - self.next_layer.before_1st_callon() - - def after_last_cb(self): - """ - callback after the last of iteration - """ - if self.next_layer!=None: - self.next_layer.after_last_callon() - - def before_1st_call(self):pass - def after_last_call(self):pass - def start_call(self):pass - def end_call(self):pass - - def __iter__(self,): - for element in self.iterable: - if self._loop_layer ==0: - self.update_i() - self.core.element = element - self.callon() - yield self.element - - def __getattr__(self,k): - return getattr(self.core,k) - - def is_newloop(self): - """ - return Bool:Is this a new loop ready to start - """ - return (self.i==-1 or self.i==self.__len__()-1) - -# Cell -class ProgressBar(Loop): - def __init__(self,iterable=[],jupyter = True,mininterval = 1.,leave=False): - super().__init__(iterable,"ProgressBar") - """ - jupyter:bool, using the jupyter progressbar (or the console pb)? - default True - mininterval: minimun update interval - leave:bool, if true, we do not remove the progress bar at the end - default: False - """ - - if jupyter: # jupyter widget - from tqdm.notebook import tqdm - - else: # compatible for console print - from tqdm import tqdm - - self.tqdm = tqdm - self.leave = leave - self.mininterval = mininterval - self.data = dict() - - @method4all - def pgbar_data(self,data): - """ - update progress bar with python dictionary - data: python dictionary - """ - self.t.set_postfix(data) - - @method4all - def pgbar_description(self,text): - """ - update progress bar prefix with text string - """ - self.t.set_description_str(f"{text}") - - def start_call(self): - self.create_bar() - - def end_call(self): - self.t.close() - - def __call__(self): - self.t.update(1) - - def create_bar(self): - self.t = self.tqdm(total=len(self.iterable),leave=self.leave, - mininterval=self.mininterval) - -# Cell -def error_tolerate(self,downstream_func): - """ - downstream_func:Downstream function - """ - try: - downstream_func() - except Exception as e: - self.errors.append(dict(stage=downstream_func.__name__, - i=self.i, - epoch=self.epoch, - error=e)) - -class Tolerate(Loop): - """ - Tolerate any error happened downstream - layer2 = Tolerate(upstream_iterable) - # build downstream tasks - layer3 = OtherApplication(layer2) - layer3.run() - # show the happened error message - layer3.error_list() - """ - def __init__(self,iterable = []): - super().__init__(iterable,) - self.errors = list() - # wrap downstream task with error tolerate - for decorator in [self.downstream, - self.downstream_start, - self.downstream_end]: - decorator(error_tolerate) - - @method4all - def error_list(self): - """ - A list of errors happend so far - """ - return self.errors - - def end_call(self,): - le = len(self.error_list()) - if le>0: - print(f"WARNING:{le} errors") - -class LambdaCall(Loop): - def __init__(self,iterable = [], - func = lambda x:x, - start_func = lambda x:x, - end_func = lambda x:x - ): - super().__init__(iterable,name=f"Lambda<{hex(id(self))}>") - self.func = func - self.start_func = end_func - self.end_func = end_func - - def __call__(self): - self.func(self) - - def start_call(self): - self.start_func(self) - - def end_call(self): - self.end_func(self) - -# Cell - -class Event(Loop): - """ - An event is the landmark with in 1 iteration - """ - def __init__(self,iterable=[]): - event_name = self.__class__.__name__ - super().__init__(iterable,event_name) - self.event_name = event_name - self.cbs = [] - self.create_cb_deco("on") - self.create_cb_deco("before_1st") - self.create_cb_deco("every_start") - self.create_cb_deco("every_end") - self.create_cb_deco("after_last") - self.core.update_forall(self) - self.core.assign_forall(self) - - def __repr__(self): - return f"event🌏{self.event_name}" - - def create_cb_deco(self,moment): - event_name = self.event_name - def wraper(cls,f):return getattr(self,moment)(f) - wraper.__name__ = f"{moment}_{event_name}" - wraper.__doc__ = f""" - Append new {moment} callback for event:{event_name} - Use this function as decorator - """ - setattr(self,wraper.__name__,MethodType(method4all(wraper),self)) - - def __call__(self): - if len(self.cbs)>0: - self.cbs[0].callon() - - def start_call(self): - if len(self.cbs)>0: - self.cbs[0].start_callon() - - def end_call(self): - if len(self.cbs)>0: - self.cbs[0].end_callon() - - def on(self,f): - class EventCB(Loop): - def __init__(self_,iterable=[]): - super().__init__(iterable=iterable, - name = f"ON_{self.event_name}_{self.cbs.__len__()+1}_{f.__name__}") - self_.f = f - - def __call__(self_): self_.f(self) - - new_cb = EventCB() - self.new_event_cb(new_cb) - return f - - def every_start(self,f): - class EventCbEveryStart(Loop): - def __init__(self_,iterable=[]): - super().__init__(iterable=iterable, - name = f"EVERY_START_{self.event_name}_{self.cbs.__len__()+1}_{f.__name__}") - self_.f = f - - def start_call(self_): self_.f(self) - - new_cb = EventCbEveryStart() - self.new_event_cb(new_cb) - return f - - def before_1st(self,f): - class EventCbBefore1st(Loop): - def __init__(self_,iterable=[]): - super().__init__(iterable=iterable, - name = f"BEFORE_1ST_{self.event_name}_{self.cbs.__len__()+1}_{f.__name__}") - self_.f = f - - def before_1st_call(self_): self_.f(self) - - new_cb = EventCbBefore1st() - self.new_event_cb(new_cb) - return f - - def every_end(self,f): - class EventCbEveryEnd(Loop): - def __init__(self_,iterable=[]): - super().__init__(iterable=iterable, - name = f"EVERY_END_{self.event_name}_{self.cbs.__len__()+1}_{f.__name__}") - self_.f = f - - def end_call(self_): self_.f(self) - - new_cb = EventCbEveryEnd() - self.new_event_cb(new_cb) - return f - - def after_last(self,f): - class EventCbAfter(Loop): - def __init__(self_,iterable=[]): - super().__init__(iterable=iterable, - name = f"AFTER_LAST_{self.event_name}_{self.cbs.__len__()+1}_{f.__name__}") - self_.f = f - - def after_last_call(self_): self_.f(self) - - new_cb = EventCbAfter() - self.new_event_cb(new_cb) - return f - - def new_event_cb(self,new_cb): - new_cb.core.update_forall(new_cb) - new_cb.core.assign_forall(new_cb) - new_cb.core = self.core - if len(self.cbs)>0: - self.cbs[-1].next_layer = new_cb -# self.cbs[-1].new_layer(new_cb) - self.cbs.append(new_cb) - -# Cell -from joblib import Parallel,delayed - -# Cell -def chunkify(*iterables,bs = 32): - if len(iterables)>1: - return list(tuple(l[i*bs:(i+1)*bs] for l in iterables) \ - for i in range(math.ceil(len(iterables[0])/bs))) - else: - return list(iterables[0][i*bs:(i+1)*bs] \ - for i in range(math.ceil(len(iterables[0])/bs))) \ No newline at end of file diff --git a/forgebox/loopstack.py b/forgebox/loopstack.py deleted file mode 100644 index 59df7a2..0000000 --- a/forgebox/loopstack.py +++ /dev/null @@ -1,263 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/15_loopstack.ipynb (unless otherwise specified). - -__all__ = ['create_event', 'events', 'LoopStack', 'MetricTab', 'train_callbacks', 'eval_callbacks', 'to_tensor', - 'simple_forward', 'single_device', 'TrainLoop', 'EvalLoop', 'find_stuff', 'share_stuff'] - -# Cell -from .loop import StorageCore,Loop,ProgressBar,Tolerate,Event,Stuff,chunkify -from types import MethodType -from datetime import datetime -import numpy as np -import pandas as pd -from time import sleep - -# Cell -def create_event(event_name): - class BatchEvent(Event):pass - BatchEvent.__name__ = event_name - return BatchEvent - -def events(*enames): - return list(map(create_event,enames)) - -# Cell -class LoopStack(Loop): - settings = [] - """ - A stack of loop - """ - @classmethod - def from_loops(cls,*loops): - def init(self,iterable=[],name = None): - name = name if name!=None else cls.__name__ - - self.loops = dict() - l = Loop(iterable) - for L in loops: l = L(iterable = l) - super().__init__(iterable = l, - name = name) - - for stuff in cls.settings: - self.make_stuff(stuff) - - setattr(cls,"init",init) - return cls - - @classmethod - def new_setting(cls,*settings): - cls.settings+=list(settings) - - def make_stuff(self,name): - new_stuff = Stuff(name) - setattr(self.core,name,new_stuff) - setattr(self,name,new_stuff) - - def __repr__(self,): - return f"LoopStack>:{self.name}\n\t"+\ - "\n\t".join(map(str,self.core.layers[:-1])) - -# Cell -class MetricTab: - """ - An object handling metric running - """ - def __init__(self): - self.df_by_epoch = [] - self.mean_by_epoch = [] - self.refresh_list() - - def __add__(self,row): - self.results.append(row) - return self - - def summary(self): - """The summary on metrics""" - return pd.DataFrame(self.mean_by_epoch) - - def update(self,**batch): - self.batch.append(batch) - return self - - def result_df(self): - return pd.DataFrame(self.results) - - def batch_df(self): - return pd.DataFrame(self.batch) - - def refresh_list(self): - self.batch = [] - self.results = [] - - def calc_mean(self,result_df,batch_df): - product_df = pd.DataFrame(dict((col,result_df[col]*batch_df["bs"]) for col in self.result_cols)) - batch_mean = dict() - for col in self.result_cols: - batch_mean[col] = product_df[col].sum()/batch_df["bs"].sum() - batch_mean["epoch"] = len(self.mean_by_epoch)+1 - batch_mean["span"] = batch_df.ts.max()-batch_df.ts.min() - return batch_mean - - def mark(self): - result_df = self.result_df() - batch_df = self.batch_df() - - self.result_cols = result_df.columns - for col in self.result_cols: - batch_df[col] = result_df[col] - - batch_mean = self.calc_mean(result_df,batch_df) - - self.df_by_epoch.append(batch_df) - self.mean_by_epoch.append(batch_mean) - - self.refresh_list() - - return batch_df, batch_mean - -# Cell -def train_callbacks(loop:Loop)->"A cluster of callback function": - """ - call backs allow optimizing model weights - """ - loop.core.metric_tab = MetricTab() - - @loop.every_start_FORWARD - def switch_model_to_train(loop:Loop): loop.model("train")() - - @loop.on_DATA_PROCESS - def opt_zero_grad(loop:Loop):loop.opt("zero_grad")() - - @loop.on_BACKWARD - def opt_move(loop:Loop): - loop.loss("backward")() - loop.opt("step")() - -def eval_callbacks(loop:Loop): - loop.core.metric_tab = MetricTab() - @loop.on_DATA_PROCESS - def switch_model_to_eval(loop:Loop): loop.model("eval")() - -def to_tensor(x): - return torch.Tensor(x) - -def simple_forward(metric_func:list = [])->"A cluster of callback function": - def simple_forward_cb(self): - @self.on_DATA_PROCESS - def set_xy(self): - self.var.clear() - self.var.x,self.var.y = self.element - self.var.apply(to_tensor,scope = ["x","y"])() - - @self.on_FORWARD - def forward_pass(self): - y_ = self.model()(self.var.x) - self.var.y_ = y_.popitem()[1][:,0] - - @self.on_LOSS_CALC - def calculate_loss(self): - losses = self.loss_func()(self.var.y_,self.var.y) - self.loss.update(losses) - - @self.on_METRICS - def calcualte_metrics(self): - # calculate metrics - with torch.no_grad(): - metrics = self.metric_func()(self.var.y_,self.var.y) - self.metric.update(metrics) - - @self.on_METRICS - def to_item(self): - # loop through metrics - self.metric.update(self.loss.cases) - dt = dict((k,v.item() if is_tensor(v) else v) \ - for k,v in self.metric.cases.items()) - self.metric_tab+=dt - self.pgbar_data(dt) - - @self.on_METRICS - def save_batch_row(self): - self.metric_tab.update( - bs = self.var.x.size(0), - epoch = self.epoch, - i = self.i, - ts = datetime.now() - ) - - @self.every_end_METRICS - def show_metric(self): - self.metric_tab.mark() - summary =self.metric_tab.summary() - try: - from IPython.display import clear_output - clear_output() - display(summary) - except: - print(summary) - - return simple_forward_cb - -def single_device(device): - def single_device_callback(self): - @self.on_DATA_PROCESS - def var_to_device(self): - self.var.apply("to")(device) - - @self.before_1st_FORWARD - def model_to_device(self): - self.model.apply("to")(device) - - return single_device - -# Cell -import torch -from torch import is_tensor - -class TrainLoop(LoopStack): - def __init__(self,data_iter,model=[],opt=[],loss_func=[],loss=[],hp=[],cuda=[], - callbacks = [train_callbacks,],tolerate=True): - loops = [ProgressBar,] - if tolerate: - loops.append(Tolerate) - loops+=list(events(*TRAIN_EVENTS)) - self.from_loops(*loops) - self.new_setting("model","var", - "opt","loss_func","loss", - "hp","cuda","metric_func","metric") - self.init(data_iter,) - for cb in callbacks: - print(f"assigning callback {cb}") - cb(self) - -# @classmethod -# def from_config(cls,train_data,val_data,model,opt,) - -class EvalLoop(LoopStack): - def __init__(self,data_iter,callbacks,tolerate=False): - loops = [ProgressBar,] - if tolerate: - loops.append(Tolerate) - loops+=list(events(*EVAL_EVENTS)) - self.from_loops(*loops) - self.new_setting("model","var", - "loss_func","loss", - "hp","cuda","metric_func","metric") - self.init(data_iter,) - - for cb in callbacks: - print(f"assigning callback {cb}") - cb(self) - - @self.FORWARD.downstream - def torch_eval_wrap(self,func): - with torch.no_grad(): - func() - -# Cell -def find_stuff(core:StorageCore): - klist = list(filter(lambda k:hasattr(getattr(core,k),"_is_stuff"), vars(core).keys())) - return dict((k,getattr(core,k)) for k in klist) - -def share_stuff(loop_from:Loop,loop_to:Loop): - stuff_dict = find_stuff(loop_from.core) - for k,v in stuff_dict.items(): - setattr(loop_to.core,k,v) \ No newline at end of file diff --git a/forgebox/minimum.py b/forgebox/minimum.py deleted file mode 100644 index d8f2e1a..0000000 --- a/forgebox/minimum.py +++ /dev/null @@ -1,161 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/21_minimum.ipynb (unless otherwise specified). - -__all__ = ['now', 'Link'] - -# Cell -from .config import Config -from datetime import datetime -from uuid import uuid4 -from inspect import getargspec -from copy import deepcopy - -# Cell -def now():return datetime.now().timestamp() - -class Link: - is_link_identifier = True - data = Config() - inputs = Config() - verbose = 0 - def __init__(self,func): - self.ensure_funcs() - func_name = func.__name__ - self.func_name = func_name - self.funcs_[func_name] = func - self.func = self.funcs_[func_name] - self.register_args() - - def __repr__(self,): - return f"[Link Function]:{self.func}" - - def ensure_funcs(self,): - if hasattr(self,"funcs_")==False: - self.__class__.funcs_ = Config() - - def ensure_uuid(self,uuid:str)->str: - """ - Make sure there's uuid, - if not create on - """ - if uuid == False: - uuid = str(uuid4()) - self.data[uuid] = Config() - self.inputs[uuid] = Config() - return uuid - else: - return uuid - - def check_callback(self,v,uuid): - - if hasattr(v,"is_link_identifier")==False: - # this is not a callback function - return v - - elif v.func_name in self.data[uuid]: - # found calculated result of the function - # read the cached result - if self.verbose>0: - print(f"[{self.func_name}] using cache:\t{v.func_name}") - return self.data[uuid].get(v.func_name) - - else: - # calculated result of function v not found, - # execuate the calculation - if self.verbose>0: - print(f"[{self.func_name}] execute callback:\t{v.func_name}") - result = v.unit_call(uuid)() - return result - - @staticmethod - def value_only(dict_:Config)->Config: - """ - filter out the value that requires callback - """ - return Config((k,v) for k,v in dict_.items() if hasattr(v,"is_link_identifier")==False) - - @staticmethod - def callback_only(dict_:Config)->Config: - """ - filter out the value that does not require callback - """ - return Config((k,v) for k,v in dict_.items() if hasattr(v,"is_link_identifier")==True) - - def get_cached(self,uuid:str)->Config: - """ - Get the cached data - """ - this_data = self.data[uuid] - return Config((k,this_data.get(k)) for k in self.all_argname \ - if k in this_data) - - def unit_call(self,uuid = False): - uuid = self.ensure_uuid(uuid) - - def called(*args,**kwargs): - # record inputs - kwargs0 = deepcopy(self.kwargs_default) - kwargs0.update(kwargs) - - # save inputs - self.inputs[uuid].update(Config({self.func_name:Config(args = args, - kwargs = kwargs0)})) - # save data - self.data[uuid].update(self.value_only(kwargs0)) - - # check the cache for all args - cached = self.get_cached(uuid) - kwargs0.update(cached) - - # check the callback trigger - args0 = list(self.check_callback(a,uuid) for a in args) - kwargs0 = dict((k,self.check_callback(v,uuid)) for k,v in kwargs0.items()) - - # redundant keywords - if (len(args0)>0) and len(self.arg_spec.args)>=len(args0): - manual_args = self.arg_spec.args[:len(args0)] - for k in manual_args: - if k in kwargs0: - del kwargs0[k] - if len(args0)>len(manual_args): - # TODO: continue development - for arg in args0[-len(manual_args):]: - pass - - # run function - if self.verbose > 1: - print(f"[{self.func_name}] final args {args0}") - print(f"[{self.func_name}] final kwargs {kwargs0}") - rt = self.func(*args0,**kwargs0) - - # save outputs - if hasattr(rt,'items'): - self.data[uuid].update(rt) - self.data[uuid].update({self.func_name:rt}) - - return rt - return called - - def __call__(self,*args,**kwargs,): - return self.unit_call()(*args,**kwargs) - - def register_args(self)->None: - """ - Register all the arguements - """ - arg_spec = getfullargspec(self.func) - self.arg_spec = arg_spec - - # gather all the default **keyword** arguments - kwargs_default = dict() - if arg_spec.defaults != None: - kwargs_default.update(dict(zip(arg_spec.args[::-1],arg_spec.defaults[::-1]))) - if arg_spec.kwonlydefaults != None: - kwargs_default.update(dict(zip(arg_spec.kwonlyargs[::-1],arg_spec.kwonlydefaults[::-1]))) - self.kwargs_default = kwargs_default - - # gather all the arg,kwarg name - self.all_argname = [] - if len(arg_spec.args)>0: - self.all_argname+=arg_spec.args - if len(arg_spec.kwonlyargs)>0: - self.all_argname+=arg_spec.kwonlyargs \ No newline at end of file diff --git a/forgebox/multiproc.py b/forgebox/multiproc.py deleted file mode 100644 index 3fed27e..0000000 --- a/forgebox/multiproc.py +++ /dev/null @@ -1,174 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/09_multiprocess.ipynb (unless otherwise specified). - -__all__ = ['VipaClass', 'SingleFileLiner', 'DataFrameRowling'] - -# Cell -from pathlib import Path -import logging -from typing import List, Dict, Callable, Any, Tuple -import random -from multiprocessing import Process - -# Cell -class VipaClass: - """ - From meditation word Vipassana - Where creating a magic function - you can run a cell without holding the entire notebook - ```ipython - %%vipas - ...do things - ``` - """ - def __init__(self): - self.procs = [] - - def vipas(self, line, cell): - """ - run a cell magic function, that will not hold the process - """ - ishell = get_ipython() - proc = Process(target=ishell.run_cell, args = (cell,), daemon=True) - proc.start() - self.procs.append(proc) - -try: - ishell = get_ipython() - from IPython.core import magic - vipa_class = VipaClass() - magic.register_cell_magic(vipa_class.vipas) - vipas = vipa_class.vipas -except: - pass - -# Cell -class SingleFileLiner: - """ - Text data reading line by line for multiprocessing - """ - - def __init__(self, file_path: Path, total: int = None): - """ - filepath: Path, - path to a textual file - total: int - if you set total to an integer, we'll have a fixed length interation object - if you set total to None, we'll read the file till it's over - """ - self.file_path = Path(file_path) - global SingleFileLiner_fp - SingleFileLiner_fp = open(file_path, "r") - global text_line_num - text_line_num = 0 - self.total = total - - def __repr__(self) -> str: - return f"SingleFileLiner:\t{self.file_path}" - - def __next__(self) -> str: - global SingleFileLiner_fp - line = SingleFileLiner_fp.readline() - global text_line_num - text_line_num += 1 - if line == "": - if self.total is None: - raise StopIteration(f"SingleFileLiner file read finish") - logging.warning(f"looping on {self.file_path}") - - self.restart() - return line.strip() - - def __len__(self): - if self.total is not None: - return self.total - else: - raise RuntimeError(f"You have to set total for len(self)") - - def __iter__(self) -> str: - if self.total is None: - while True: - try: - yield next(self) - except StopIteration: - # end the file reading - break - else: - for i in range(self.total): - yield next(self) - - def restart(self) -> None: - """resetart file reader""" - global SingleFileLiner_fp - SingleFileLiner_fp.close() - SingleFileLiner_fp = open(self.file_path, "r") - - def split_train_test( - self, - val_ratio: float = 0.1, - remove_original: bool = False, - logging_interval: int = 1000000) -> Tuple[Path]: - """ - Split the text file into train and test - :param val_ratio: - :return: - """ - suffix = self.file_path.suffix - - train_file_path = self.file_path.parent / \ - f"{self.file_path.stem}_train{suffix}" - valid_file_path = self.file_path.parent / \ - f"{self.file_path.stem}_valid{suffix}" - - # delete the file if exists - if remove_original: - train_file_path.unlink() - valid_file_path.unlink() - - # read and write by line - with open(self.file_path, "r") as f, open( - train_file_path, "w") as f_train, open( - valid_file_path, "w") as f_valid: - for i, line in enumerate(f): - if i % 1000000 == 0: - logging.info(f"{i}\tlines processed") - if random.random() < val_ratio: - f_valid.write(line) - else: - f_train.write(line) - return train_file_path, valid_file_path - -# Cell -class DataFrameRowling: - """ - Read dataframe row by row - """ - def __init__(self, df): - self.df = df - self.restart() - - def restart(self): - global DataFrameRowling_df - DataFrameRowling_df = self.df - global DataFrameRowling_ct - DataFrameRowling_ct = 0 - - def __repr__(self) -> str: - return f"DataFrameRowling:\t{len(self)} Rows" - - def __len__(self): - return len(self.df) - - def __iter__(self): - for i in range(len(self)): - yield next(self) - - def __getitem__(self, idx): - global DataFrameRowling_df - return DataFrameRowling_df[list(DataFrameRowling_df.index)[idx]] - - def __next__(self): - global DataFrameRowling_df - global DataFrameRowling_ct - row = DataFrameRowling_df.loc[list(DataFrameRowling_df.index)[DataFrameRowling_ct]] - DataFrameRowling_ct+=1 - return row \ No newline at end of file diff --git a/forgebox/multitask_ce.py b/forgebox/multitask_ce.py deleted file mode 100644 index 3452d5c..0000000 --- a/forgebox/multitask_ce.py +++ /dev/null @@ -1,37 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/cross_entropy_weighter.ipynb (unless otherwise specified). - -__all__ = ['MultiTaskCELoss'] - -# Cell -import torch -from torch import nn -import pandas as pd -import numpy as np -from typing import Callable - -# Cell -class MultiTaskCELoss(nn.Module): - """ - A cross entropy loss function which will cancel out - the effect of different class numbers - """ - def __init__(self,): - super().__init__() - self.celoss = nn.CrossEntropyLoss() - - def forward( - self, - y_pred: torch.FloatTensor, - y_true: torch.LongTensor, - )-> torch.FloatTensor: - """ - Input: - - y_pred: torch.FloatTensor, Prediction tensor - - y_true: torch.LongTensor, Label indices - Return: - - loss: torch.FloatTensor, scala adjusted - """ - nb_classes = y_pred.size(-1) - lambda_ = 1/np.log10(nb_classes) - loss = self.celoss(y_pred,y_true) - return loss*lambda_ \ No newline at end of file diff --git a/forgebox/pdenhanced.py b/forgebox/pd_plus.py similarity index 65% rename from forgebox/pdenhanced.py rename to forgebox/pd_plus.py index a683e96..421545e 100644 --- a/forgebox/pdenhanced.py +++ b/forgebox/pd_plus.py @@ -1,12 +1,10 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/01_pandas_extra.ipynb (unless otherwise specified). - __all__ = ['list_vc', 'col_list_vc', 'default_rename_rule', 'rename_by_rule', 'column_order'] -# Cell import pandas as pd from typing import Callable +import numpy as np + -# Cell def list_vc( df, colname: str, value: str ) -> pd.DataFrame: @@ -31,7 +29,27 @@ def col_list_vc( pd.Series.list_vc = col_list_vc pd.DataFrame.list_vc = list_vc -# Cell +def split(df, valid=0.2, ensure_factor=2): + """ + df: dataframe + valid: valid ratio, default 0.1 + ensure_factor, ensuring the row number to be the multiplication of this factor, default 2 + return train_df, valid_df + """ + split_ = (np.random.rand(len(df)) > valid) + train_df = df[split_].sample(frac=1.).reset_index().drop("index", axis=1) + valid_df = df[~split_].sample(frac=1.).reset_index().drop("index", axis=1) + + if ensure_factor: + train_mod = len(train_df) % ensure_factor + valid_mod = len(valid_df) % ensure_factor + if train_mod: train_df = train_df[:-train_mod] + if valid_mod: valid_df = valid_df[:-valid_mod] + return train_df, valid_df + +pd.DataFrame.split = split + + def default_rename_rule(x: str) -> str: return x.replace(" ", "_").replace("-", "_").lower() @@ -49,7 +67,7 @@ def rename_by_rule( pd.DataFrame.rename_by_rule = rename_by_rule -# Cell + def column_order(df, *col_names) -> pd.DataFrame: """ df = df.column_order("col1", "col2", "col3") @@ -66,4 +84,5 @@ def column_order(df, *col_names) -> pd.DataFrame: cols.insert(0, cols.pop(cols.index(col_name))) return df[cols] -pd.DataFrame.column_order = column_order \ No newline at end of file +pd.DataFrame.column_order = column_order + diff --git a/forgebox/pipe.py b/forgebox/pipe.py deleted file mode 100644 index 393ad90..0000000 --- a/forgebox/pipe.py +++ /dev/null @@ -1,251 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/dataframe_pipeline.ipynb (unless otherwise specified). - -__all__ = ['Node', 'chunkNode', 'frameEdge', 'colEdge', 'donothing', 'nothing', 'fillNaEdge', 'engTokEdge', 'CNTok', - 'capMinMaxEdge', 'trackVocabEdge', 'saveCSV', 'saveSQL', 'eng_twt_tk'] - -# Cell -import numpy as np -import pandas as pd -from itertools import chain -from collections import Counter - -# Cell -class Node(object): - def __init__(self, df, verbose=1): - super(Node,self).__init__() - self.df = df - self.verbose = verbose - self.pipenames = list() - self.pipe = list() - - def __repr__(self): - return "\n\t|"+"\n\t|".join(self.pipenames) - - def __or__(self, edge): - """ - use it as: - node|edge|edge - :param process_step: - :return: - """ - self.pipe.append(edge) - self.pipenames.append(edge.edge_name) - return self - - def run(self): - for pro_i in range(len(self.pipe)): - if self.verbose > 0: print("[df edge]:%s" % self.pipenames[pro_i]) - pro = self.pipe[pro_i] - self.df = pro.pro(self.df) - return self.df - -class chunkNode(Node): - def __init__(self, df_chunk, verbose=1): - """ - Use this class instead of Node class, for huge data sourse like big csv or huge SQL table - chunkNode(pd.read_csv("xxx.csv",chunksize = 1000), verbose =1) - :param df_chunk: pandas dataframe with chunksize parameter - :param verbose: - """ - super(chunkNode, self).__init__(df = df_chunk, verbose = verbose) - self.df_chunk = self.df - - def run(self): - """ - Running iterations on the entire dataset - :return: None - """ - for df in self.df: - for pro_i in range(len(self.pipe)): - if self.verbose > 0: print("[df edge]:%s" % self.pipenames[pro_i]) - pro = self.pipe[pro_i] - df = pro.pro(df) - - def testrun(self): - """ - testing for 1 iteration - :return: the result dataframe - """ - testdf = next(self.df) - print("Please restart the generator after running test",flush=True) - for pro_i in range(len(self.pipe)): - if self.verbose > 0: print("[df edge]:%s" % self.pipenames[pro_i]) - pro = self.pipe[pro_i] - testdf = pro.pro(testdf) - - return testdf - -# Cell -class frameEdge(object): - def __init__(self, edge_name=None): - super(frameEdge, self).__init__() - if edge_name == None: - edge_name = "DataFrame_Processing_Edge" - self.edge_name = edge_name - self.i = None - - def __mul__(self, cols): - assert 0, "Only colEdge support * columns operation" - - def define(self, f): - def wraper(df): - return f(df) - - self.pro = wraper - return wraper - - -class colEdge(object): - def __init__(self, edge_name=None): - super().__init__() - if edge_name == None: - edge_name = "DataSeries_Processing_Edge" - self.edge_name = edge_name - self.cols = [] - - def __mul__(self, cols): - self.cols = cols - return self - - def __mod__(self,col): - self.cols = [col] - return self - - def define(self, f): - def wraper(col): - col = f(col) - return col - - self.colpro = wraper - return wraper - - def pro(self, df): - for c in self.cols: - df[c] = self.colpro(df[c]) - return df - -nothing = frameEdge("empety_process") - -@nothing.define -def donothing(df): - return df - -# Cell -class fillNaEdge(colEdge): - def __init__(self, fill=0.): - super().__init__("fillna_%s"%(fill)) - self.fill = fill - - def colpro(self, col): - return col.fillna(self.fill) - - -class engTokEdge(colEdge): - def __init__(self, tokenizer=None, max_len=None): - """ - Default using tweet tokenizer - """ - super().__init__("En Tokenization") - if tokenizer ==None: - from nltk.tokenize import TweetTokenizer - self.tokenizer = TweetTokenizer() - else: - self.tokenizer = tokenizer - self.max_len = max_len - - def colpro(self, c): - return c.apply(lambda x: self.tokenizer.tokenize(x)[:self.max_len]) - -eng_twt_tk = engTokEdge() - -class CNTok(colEdge): - def __init__(self): - """ - cntok = CNTok() - datanode = start_node|cntok*["col1","col2"] - datanode.run() - """ - super().__init__("chinese_tokenize") - from jieba import cut - self.cut = cut - - def colpro(self, col): - col = col.apply(lambda x:list(self.cut(str(x)))) - return col - -class capMinMaxEdge(colEdge): - def __init__(self, min_ = None, max_ = None): - super().__init__("cap min:%s max:%s"%(min_,max_)) - self.min_ = min_ - self.max_ = max_ - - def colpro(self,col): - col = np.clip(col.values,a_min = self.min_, a_max = self.max_) - return col - -class trackVocabEdge(colEdge): - """ - a colEdge - input column should contain python list - This edge will keep track a vocabulary pandas DataFrame - tck_vcb = TrackVocab() - tck_vcb.vocab is the accumulated vocabulary - """ - def __init__(self): - super().__init__("track vocab") - self.vocab = pd.DataFrame({"token": [], "cnt": []}) - - def colpro(self, col): - lists = list(col) - biglist = list(chain.from_iterable(lists)) - self.vocab = self.combine_vocab(self.build_vocab(biglist)) - return col - - def get_token_count_dict(self, full_tok): - """count the token to a list""" - return Counter(full_tok) - - def build_vocab(self, full_tok): - ct_dict = self.get_token_count_dict(full_tok) - tk, ct = list(ct_dict.keys()), list(ct_dict.values()) - - return pd.DataFrame({"token": tk, "cnt": ct}) - - def combine_vocab(self, new_vocab): - combinedf = pd.concat([self.vocab, new_vocab]).groupby("token").sum().reset_index() - return combinedf.sort_values(by="cnt", ascending=False).reset_index().rename(columns = {"index":"idx"}) - - def save_vocab(self, json_url): - self.vocab.to_json(json_url) - - -class saveCSV(frameEdge): - """ - DataFrame Edge - SaveCsv("/path/to/file.csv") - """ - def __init__(self, csvpath, tocsv_conf={"sep": "\t", "index":False}): - super().__init__("save to csv") - self.csvpath = csvpath - self.tocsv_conf = tocsv_conf - self.header = True - - def pro(self, df): - df.to_csv(self.csvpath,header=self.header, mode="a", **self.tocsv_conf) - self.header = False - return df - -class saveSQL(frameEdge): - """ - DataFrame Edge - SaveSQL("table_name", con) - """ - def __init__(self, table_name, con, tosql_conf={"index": False, "if_exists":"append"}): - super().__init__("save to sql_table") - self.table_name = table_name - self.con = con - self.tosql_conf = tosql_conf - - def pro(self, df): - df.to_sql(self.table_name, con=self.con, **self.tosql_conf) - return df \ No newline at end of file diff --git a/forgebox/spacy.py b/forgebox/spacy.py deleted file mode 100644 index 417804a..0000000 --- a/forgebox/spacy.py +++ /dev/null @@ -1,156 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/06_spacy.ipynb (unless otherwise specified). - -__all__ = ['l2norm', 'normal', 'distance', 'make_map', 'make_span', 'make_div', 'doc2div', 'compare_sentences', - 'highlight'] - -# Cell -from .html import DOM,JS -import numpy as np -import json - -# Cell -def l2norm(x):return np.sqrt(np.power(x,2).sum(-1)) -def normal(x):return (x/l2norm(x)[:,None]) -def distance(a,b):return 1- normal(a)@(normal(b).T) - -# Cell - -highlight = """ -$(document).ready(function(){ - const red=(dom)=>{ - $(dom) - .css("background-color","#FFCCEE") - .css("box-shadow","0px 0px 10px #FFCCEE") - } - const white=(dom)=>{ - $(dom).css("background-color","#FFFFFF") - .css("box-shadow","0px 0px 0px #FFFFFF") - } - $(".nlp_tok") - .css("margin","1px 2px") - .css("padding","1px 1px") - .css("border-radius","5px"); - var edge = JSON.parse(window.edge_data) - var edge2 = JSON.parse(window.edge_data2) - var all_b = [] - for(var a in edge) - { - $(`#map_word_src_${a}`).data("match",edge[a].idx) - $(`#map_word_src_${a}`).css("font-weight",900) - $(`#map_word_src_${a}`) - .hover(function(){ - red(this) - var b_match = $(this).data("match") - for(var i in b_match){ - var b = b_match[i] - red(document.querySelector(`#map_word_tgt_${b}`)) - } - }) - $(`#map_word_src_${a}`) - .mouseleave(function(){ - white(this) - var b_match = $(this).data("match") - for(var i in b_match){ - var b = b_match[i] - white(document.querySelector(`#map_word_tgt_${b}`)) - } - }) - } - for(var a in edge2) - { - $(`#map_word_tgt_${a}`).data("match",edge2[a].idx) - $(`#map_word_tgt_${a}`).css("font-weight",900) - $(`#map_word_tgt_${a}`) - .hover(function(){ - red(this) - var b_match = $(this).data("match") - for(var i in b_match){ - var b = b_match[i] - red(document.querySelector(`#map_word_src_${b}`)) - } - }) - $(`#map_word_tgt_${a}`) - .mouseleave(function(){ - white(this) - var b_match = $(this).data("match") - for(var i in b_match){ - var b = b_match[i] - white(document.querySelector(`#map_word_src_${b}`)) - } - }) - } - -}) -""" -def make_map(distance_map,th = .1): - """ - create a hot spot map between similar token - return dict, token index with matching token index in the target sentence - """ - a2b_dict = dict() - tgt_range = np.arange(distance_map.shape[-1]) - for i in range(len(distance_map)): - slice_ = (distance_map[i,:]0: - a2b_dict[str(i)]= dict(dist = list(distance_map[i,:][slice_].astype(float)), - idx = list(tgt_range[slice_].astype(str))) - return a2b_dict - -def make_span(tok,tok_id,classes): - """ - create span for token - tok,spacy token - tok_id, span's html id - - return forgebox.html.DOM - """ - return DOM(tok.text,"span",{"class":" ".join(classes),"id":tok_id}) - -def make_div(doc,id_list,classes_list): - """ - create div tag for a sentence - doc:spacy doc - id_list, a list of html id - classes_list, a list of classes assigning to the token span - - return forgebox.html.DOM - """ - div = DOM("","div",{"class":"text-block"}) - for tok,tok_id,classes in zip(doc,id_list,classes_list): - div.append(make_span(tok,tok_id,classes)) - return div - -def doc2div(doc,distance_map,th=.1,is_src= True): - totallen = len(doc) - src_tgt = "src" if is_src else "tgt" - id_list = list(f"map_word_{src_tgt}_{i}" for i in range(len(doc))) - if is_src: - edge_map = make_map(distance_map,th=th) - DOM(f"window.edge_data = '{json.dumps(edge_map)}'","script")() - else: - edge_map2 = make_map(distance_map.T,th=th) - DOM(f"window.edge_data2 = '{json.dumps(edge_map2)}'","script")() - - return make_div(doc,id_list,zip([src_tgt,]*totallen,["nlp_tok"]*totallen)) - - - -def compare_sentences(A,B,nlp,th=.1): - """ - Compare between sentences - A: str, a sentence - B: str, another sentence - nlp: loaded spacy: eg. from spacy import load;nlp = load("some_model_name"), - see spacy documentation https://spacy.io/usage/spacy-101/ - - th:float, threshold for consine distance, smaller it is, fewer matching tokens will be found, - but assume that means higher quality - """ - doc_a = nlp(A) - doc_b = nlp(B) - distance_map = distance(doc_a.tensor,doc_b.tensor) - DOM("Sentence A","h3",{"class":"text-primary"})() - doc2div(doc_a,distance_map,th=th,is_src=True)() - DOM("Sentence B","h3",{"class":"text-primary"})() - doc2div(doc_b,distance_map,th=th,is_src=False)() - JS(highlight) \ No newline at end of file diff --git a/forgebox/static_file.py b/forgebox/static_file.py deleted file mode 100644 index 8bd7a89..0000000 --- a/forgebox/static_file.py +++ /dev/null @@ -1,17 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/12_static_file.ipynb (unless otherwise specified). - -__all__ = ['get_static', 'open_static'] - -# Cell -from pathlib import Path -def get_static()->Path: - """ - return the absolute path of forgebox.static - """ - import forgebox - return Path(forgebox.__path__[0])/"static" - -def open_static(relative_path:str)->str: - file = get_static()/relative_path - with open(file,"r") as f: - return f.read() \ No newline at end of file diff --git a/forgebox/tensor.py b/forgebox/tensor.py deleted file mode 100644 index 74942cd..0000000 --- a/forgebox/tensor.py +++ /dev/null @@ -1,45 +0,0 @@ -__all__ = ['modules_to_opt_conf','measure_freeze','numpify'] - -from copy import deepcopy -from torch import nn - -def modules_to_opt_conf(*modules,**opt_kwargs)->"a list of PyTorch optimizer config": - """ - put in a sequence of pytorch modules, - return optimizer param groups of configs - """ - param_list = [] - param_list_nd = [] - no_decay = ["bias", "LayerNorm.weight"] - - for m in modules: - for n,p in m.named_parameters(): - if any(nd in n for nd in no_decay): - param_list_nd.append(p) - else: - param_list.append(p) - - opt_kwargs_nd = deepcopy(opt_kwargs) - opt_kwargs_nd["weight_decay"]=0. - - return [dict(params=param_list,**opt_kwargs), # param_group with weight decay - dict(params=param_list_nd,**opt_kwargs_nd), # param_group without weight decay - ] - -def measure_freeze(m:nn.Module)->"a describtion about how many submodules are unfreezed": - """ - measure the how many sub-module we freezed or unfreezed - """ - total = 0 - trainable = 0 - for param in m.parameters(): - total+=1 - if param.requires_grad: trainable+=1 - return f"{trainable} trainables/{total} total" - -def numpify(*tensors): - tensors = list(tensors) - """Transform bunch of pytorch tensors to numpy array, even if in cuda""" - for i in range(len(tensors)): - tensors[i] = tensors[i].clone().cpu().numpy() - return tensors \ No newline at end of file diff --git a/forgebox/test_nbdev.py b/forgebox/test_nbdev.py deleted file mode 100644 index 44b6c91..0000000 --- a/forgebox/test_nbdev.py +++ /dev/null @@ -1,8 +0,0 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/test_nbdev.ipynb (unless otherwise specified). - -__all__ = ['test_nbdev_func'] - -# Cell - -def test_nbdev_func(): - return 42 \ No newline at end of file diff --git a/forgebox/thunder/callbacks.py b/forgebox/thunder/callbacks.py index 07b8cbc..d942dfe 100644 --- a/forgebox/thunder/callbacks.py +++ b/forgebox/thunder/callbacks.py @@ -1,17 +1,15 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/61_thunder_callbacks.ipynb (unless otherwise specified). - -__all__ = ['unfreeze', 'freeze', 'DataFrameMetricsCallback', 'UnfreezeScheduler'] - -# Cell import pandas as pd from ipywidgets import Output -from typing import List, Dict +from typing import List import copy -import pytorch_lightning as pl -import torch +try: + import pytorch_lightning as pl +except ImportError as e: + raise ImportError("Please install pytorch-lightning first") +from forgebox.html import display from torch import nn -# Cell + def unfreeze(self): """unfreeze this module, and its sub modules""" for p in self.parameters(): @@ -23,9 +21,11 @@ def freeze(self): for p in self.parameters(): p.requires_grad = False + nn.Module.unfreeze = unfreeze nn.Module.freeze = freeze + class DataFrameMetricsCallback(pl.Callback): """ A metrics callback keep showing pandas dataframe @@ -55,24 +55,3 @@ def on_validation_epoch_end( pl_module.output.clear_output() with pl_module.output: display(pd.DataFrame(self.metrics).tail(10)) - - -def UnfreezeScheduler(frozen_epochs: int = 2): - assert hasattr(pl_module, "top_layers"), "Please define 'top_layers' attributes"+\ - " for pl_module, which will return a list of nn.Module object(s)" - class UnfreezeSchedulerCallback(pl.callbacks.Callback): - """ - Train the top layer for [frozen_epochs] epochs - then un freeze all - """ - - def on_epoch_start(self, trainer, pl_module): - epoch = trainer.current_epoch - - if epoch == 0: - pl_module.freeze() - for tl in pl_module.top_layers: - tl.unfreeze() - if epoch == frozen_epochs: - pl_module.unfreeze() - pl_module.base.embeddings.freeze() \ No newline at end of file diff --git a/forgebox/train.py b/forgebox/train.py deleted file mode 100644 index 7ee6477..0000000 --- a/forgebox/train.py +++ /dev/null @@ -1,259 +0,0 @@ -import os -from datetime import datetime -from tqdm import trange -from functools import reduce -import pandas as pd -from collections import namedtuple -from types import MethodType -from forgebox.utils import JUPYTER - -if JUPYTER: from tqdm import tqdm_notebook as tn - -TrainerBatch = namedtuple("TrainerBatch", ("epoch", "i", "data", "trainer")) - -class Trainer: - def __init__(self, train_data, train_len, val_data=None, val_len=None, batch_size=16, fg=None, - print_on=20, fields=None, is_log=True,batch_start_zg = True, - conn=None, modelName="model", tryName="try", callbacks=[], val_callbacks=[],jupyter = JUPYTER): - """ - A training iteration wraper - fields: the fields you choose to print out - is_log: writing a log? - - Training: - - write action function for a step of training, - assuming a generator will spit out tuple x,y,z in each: - then pass the function to object - - t=Trainer(...) - t.train(epochs = 30) - - @t.step_train - def action(batch): - x,y,z = batch.data - x,y,z = x.cuda(),y.cuda(),z.cuda() - - #optimizer is a global variable, or many different optimizers if you like - sgd.zero_grad() - adam.zero_grad() - - # model is a global variable, or many models if you like - y_ = model(x) - y2_ = model_2(z) - - ...... more param updating details here - - return {"loss":loss.item(),"acc":accuracy.item()} - - same work for validation:trainer.val_action = val_action - - conn: a sql table connection, (sqlalchemy). if assigned value, save the record in the designated sql database; - """ - self.batch_size = batch_size - self.conn = conn - self.fg = fg - self.modelName = modelName - self.tryName = tryName - self.train_data = train_data - self.train_len = train_len - self.val_data = val_data - self.val_len = val_len - self.print_on = print_on - self.jupyter = jupyter - - self.callbacks = callbacks - self.val_callbacks = val_callbacks - self.batch_start_zg = batch_start_zg - - self.before_train_batch_list = [] - self.before_val_batch_list = [] - - if self.val_data: - self.val_track = dict() - - self.track = dict() - self.fields = fields - self.is_log = is_log - - def one_batch(self): - if hasattr(self, "testgen") == False: - self.testgen = iter(self.train_data) - try: - return next(self.testgen) - except StopAsyncIteration: - self.testgen = iter(self.train_data) - return next(self.testgen) - - def progress(self, l): - return tn(range(l)) if self.jupyter else trange(l) - - def get_time(self): - return datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f") - - def train(self, epochs, name=None, log_addr=None): - """ - Train the model for some epochs - """ - if self.fg: - self.fg.new_train() - - for epoch in range(epochs): - self.track[epoch] = list() - self.run(epoch) - self.log(name = name,log_addr=log_addr) - - - def log(self, name, log_addr): - if self.is_log: - if name == None: - name = "torch_train_" + datetime.now().strftime("%y%m%d_%H%M%S") - if log_addr == None: - log_addr = ".log_%s" % (name) - - if log_addr[-1] != "/": log_addr += "/" - os.system("mkdir -p %s" % (log_addr)) - trn_track = pd.DataFrame(reduce((lambda x, y: x + y), list(self.track.values()))) - trn_track.to_csv(log_addr + "trn_" + datetime.now().strftime("%y_%m_%d__%H_%M_%S") + ".csv", - index=False) - - if self.val_len: - val_track = pd.DataFrame(reduce((lambda x, y: x + y), list(self.val_track.values()))) - val_track.to_csv(log_addr + "val_" + datetime.now().strftime("%y_%m_%d__%H_%M_%S") + ".csv", - index=False) - - def train_iteration(self, i, t): - self.i = i - self.data = next(self.train_gen) - - for f in self.before_train_batch_list: f() - - if self.batch_start_zg: self.opt.zero_all() - - if hasattr(self,"data_to_device"): self.data_to_device() - - ret = self.action() - ret.update({"epoch": self.epoch, - "iter": i, - "ts": self.get_time()}) - self.track[self.epoch].append(ret) - - if i % self.print_on == self.print_on - 1: - self.update_descrition(self.epoch, i, t) - - def val_action_wrap(self): - return self.val_action() - - def val_iteration(self, i ,val_t): - self.i = i - self.data = next(self.val_gen) - for f in self.before_val_batch_list: f() - - if hasattr(self, "val_data_to_device"): self.val_data_to_device() - - ret = self.val_action_wrap() - ret.update({"epoch": self.epoch, - "iter": i, - "ts": self.get_time()}) - self.val_track[self.epoch].append(ret) - self.update_descrition_val(self.epoch, i, val_t) - - def run(self, epoch): - """ - run for a single epoch - :param epoch: the epoch index - :return: - """ - t = self.progress(self.train_len) - - self.train_gen = iter(self.train_data) - self.epoch = epoch - - for i in t: - self.train_iteration(i,t) - - for cb_func in self.callbacks: - cb_func(record=self.track[epoch]) - - if self.val_len: - self.epoch = epoch - self.val_track[epoch] = list() - self.val_gen = iter(self.val_data) - - val_t = self.progress(self.val_len) - for i in val_t: - self.val_iteration(i, val_t) - - for v_cb_func in self.val_callbacks: - v_cb_func(record=self.val_track[epoch] ) - - def update_descrition(self, epoch, i, t): - window_df = pd.DataFrame(self.track[epoch][max(i - self.print_on, 0):i]) - - if self.conn: # if saving to a SQL database - window_df["split_"] = "train" - window_df["tryName"] = self.tryName + "_train" - window_df.to_sql("track_%s" % (self.modelName), con=self.conn, if_exists="append", index=False) - window_dict = dict(window_df.mean()) - del window_dict["epoch"] - del window_dict["iter"] - - desc = "⭐[ep_%s_i_%s]" % (epoch, i) - if self.jupyter: - t.set_postfix(window_dict) - else: - if self.fields != None: - desc += "✨".join(list("\t%s\t%.3f" % (k, v) for k, v in window_dict.items() if k in self.fields)) - else: - desc += "✨".join(list("\t%s\t%.3f" % (k, v) for k, v in window_dict.items())) - t.set_description(desc) - - def update_descrition_val(self, epoch, i, t): - if self.conn: # if saving to a SQL database - window_df = pd.DataFrame(self.val_track[epoch][max(i - self.print_on, 0):i]) - window_df["split_"] = "valid" - window_df["tryName"] = self.tryName + "_valid" - window_df.to_sql("track_%s" % (self.modelName), con=self.conn, if_exists="append", index=False) - window_dict = dict(pd.DataFrame(self.val_track[epoch]).mean()) - # print(pd.DataFrame(self.val_track[epoch])) - del window_dict["epoch"] - del window_dict["iter"] - - desc = "😎[val_ep_%s_i_%s]" % (epoch, i) - if JUPYTER: - t.set_postfix(window_dict) - else: - if self.fields != None: - desc += "😂".join(list("\t%s\t%.3f" % (k, v) for k, v in window_dict.items() if k in self.fields)) - else: - desc += "😂".join(list("\t%s\t%.3f" % (k, v) for k, v in window_dict.items())) - t.set_description(desc) - - def todataframe(self, dict_): - """return a dataframe on the train log dictionary""" - tracks = [] - for i in range(len(dict_)): - tracks += dict_[i] - - return pd.DataFrame(tracks) - - def step_train(self,f): - setattr(self, "action", MethodType(f, self)) - return f - - def step_val(self,f): - setattr(self, "val_action", MethodType(f, self)) - return f - - def step_extra(self, func_name): - """ - @t.step_extra("forward_pass") - def fp(self): - self.x = self.data.x.float() - self.y = self.datay.long() - self.y_ = model(self.x) - """ - def assign(f): - setattr(self,func_name, MethodType(f, self)) - return assign - diff --git a/forgebox/usuals.py b/forgebox/usuals.py deleted file mode 100644 index 7423073..0000000 --- a/forgebox/usuals.py +++ /dev/null @@ -1,10 +0,0 @@ -import pandas as pd -import numpy as np -import torch -from torch import nn -import os -import sys -import json -from PIL import Image -from pathlib import Path -import math diff --git a/forgebox/utils.py b/forgebox/utils.py deleted file mode 100644 index 39e7c6a..0000000 --- a/forgebox/utils.py +++ /dev/null @@ -1,16 +0,0 @@ -import os -def create_dir(path): - if not os.path.exists(path): - os.makedirs(path) - -def tell_jupyter(): - import __main__ as main - - try: - JUPYTER = True if main.get_ipython else False - except: - JUPYTER = False - - return JUPYTER - -JUPYTER = tell_jupyter() \ No newline at end of file diff --git a/forgebox/widgets.py b/forgebox/widgets.py index 7e6d5fd..ce27487 100644 --- a/forgebox/widgets.py +++ b/forgebox/widgets.py @@ -5,22 +5,22 @@ # Cell import pandas as pd -import numpy as np from .df import PandasDisplay -from .html import list_group, list_group_kv +from .html import list_group, list_group_kv, display from typing import Callable, List, Tuple, Set, Dict, Any from ipywidgets import ( IntSlider, FloatSlider, Text, Textarea, Layout, Output, HBox, VBox, Button, - Select, SelectMultiple, - Dropdown, Checkbox, - IntProgress, HTML, interact, interact_manual + Dropdown, + IntProgress, + HTML ) +import json + +def display_df(df): display(df) -# Cell -def display_df(df):display(df) -def search_box(df,columns,manual = False,max_rows = 10,callback = display_df): +def search_box(df, columns, manual=False, max_rows=10, callback=display_df): """ create a search box based on dataframe df: pandas dataframe @@ -31,42 +31,44 @@ def search_box(df,columns,manual = False,max_rows = 10,callback = display_df): callback: python callable, discribe the action you want to put on search result (a filtered dataframe), default is to display the dataframe """ - from ipywidgets import interact,interact_manual + from ipywidgets import interact, interact_manual from IPython.display import HTML intera = interact_manual if manual else interact @intera - def search(KeyWord = "",): + def search(KeyWord="",): for col in columns: result = df[col].fillna("NaN Value").str.contains(KeyWord) - if sum(result)>0: - with PandasDisplay(max_colwidth=0,max_rows=max_rows): - display(HTML(f"

    \"{KeyWord}\" matched on column:[{col}]

    ")) + if sum(result) > 0: + with PandasDisplay(max_colwidth=0, max_rows=max_rows): + display( + HTML(f"

    \"{KeyWord}\" matched on column:[{col}]

    ")) callback(df[result].head(max_rows)) return print(f"Nothing found on any column on keyword:{KeyWord}") return -# Cell -def paginate(df,page_len = 20): + +def paginate(df, page_len=20): """ Paginate dataframe in jupyter notebook interactively Like you can flip through the page """ - from ipywidgets import interact,interact_manual - from IPython.display import display,HTML + from ipywidgets import interact, interact_manual + from IPython.display import display, HTML pages = len(df)//page_len + @interact - def preview(page = (0,pages)): + def preview(page=(0, pages)): display(HTML(f"

    page:{page}/{pages}")) end = (page+1)*page_len display(df.head(end).tail(page_len)) -# Cell + def make_hboxes( *widgets, - sections: int=2 + sections: int = 2 ) -> List[HBox]: """ Make a list of HBox, with each hbox @@ -75,16 +77,17 @@ def make_hboxes( sections: int """ hbox_list = [] - hbox_inner=[] + hbox_inner = [] for idx, widget in enumerate(widgets): hbox_inner.append(widget) - if idx%sections==sections-1: + if idx % sections == sections-1: hbox_list.append(HBox(hbox_inner)) - hbox_inner=[] - if len(hbox_inner)>0: + hbox_inner = [] + if len(hbox_inner) > 0: hbox_list.append(HBox(hbox_inner)) return hbox_list + class SingleButton: """ A single button widget @@ -101,12 +104,13 @@ def makeup_some_sql( return f"select * from {table} limit {limit}" ``` """ + def __init__( self, - btn_text: str="Run", - btn_style: str="danger", - callback: Callable=lambda x:x, - sections: int=2, + btn_text: str = "Run", + btn_style: str = "danger", + callback: Callable = lambda x: x, + sections: int = 2, ): """ btn_text: str, text appears on the button @@ -118,8 +122,8 @@ def __init__( self.sections = sections def create_slider( - self, k: str, - anno: dict): + self, k: str, + anno: dict): """ create int or float slider widget """ @@ -147,7 +151,7 @@ def create_text(self, k, anno): create text area widget """ if "textarea" in anno: - layout = Layout(width="100%", height="auto" ) + layout = Layout(width="100%", height="auto") wi = Textarea(description=k, layout=layout) else: wi = Text(description=k) @@ -176,7 +180,7 @@ def anno_widgets(self): create_func = self.create_dropdown else: raise TypeError(f"type {atype} not found") - self.controls.update({k:create_func(k, anno)}) + self.controls.update({k: create_func(k, anno)}) def execute(self, btn): """ @@ -196,11 +200,12 @@ def __call__(self, f: Callable): def abc(...): ... """ - self.f=f + self.f = f self.name = f.__name__ self.anno_widgets() - def wrapper(*args,**kwargs): - rt = f(*args,**kwargs) + + def wrapper(*args, **kwargs): + rt = f(*args, **kwargs) self.callback(rt) return rt @@ -219,18 +224,21 @@ def wrapper(*args,**kwargs): return f # Cell + + class Labeler: """ An interactive tool labeling pandas dataframe row by row """ + def __init__( self, df: pd.DataFrame, options_col: str, - result_col: str="label", - show_callback: Callable=None, - auto_fill_in: bool=True + result_col: str = "label", + show_callback: Callable = None, + auto_fill_in: bool = True ): """ - df: pd.DataFrame, a dataframe prepared @@ -245,13 +253,13 @@ def __init__( self.options_col = options_col if auto_fill_in: - self.df.loc[:,self.result_col] = self.df[self.options_col]\ - .apply(lambda x:x[0] if len(x)==1 else None) + self.df.loc[:, self.result_col] = self.df[self.options_col]\ + .apply(lambda x: x[0] if len(x) == 1 else None) else: - self.df.loc[:,self.result_col] = [None,]*len(self.df) + self.df.loc[:, self.result_col] = [None, ]*len(self.df) self.out = Output() - show_dict = lambda idx,row:str(dict(row)) + def show_dict(idx, row): return str(dict(row)) self.show_callback = show_dict if show_callback is None else show_callback def get_progress_bar(self, idx) -> HBox: @@ -262,7 +270,7 @@ def get_progress_bar(self, idx) -> HBox: return HBox([ IntProgress(value=i, min=0, max=len(self.df)), HTML(f"{i+1}/{len(self.df)}") - ]) + ]) def button_box( self, @@ -274,9 +282,9 @@ def button_box( """ btns = [] for o in options: - btn = Button(description = o,) - btn.value=o - btn.idx=idx + btn = Button(description=o,) + btn.value = o + btn.idx = idx btn.on_click(self.choice_cb) btns.append(btn) return HBox(btns) @@ -285,18 +293,19 @@ def choice_cb(self, option): with self.out: self.df.loc[option.idx, self.result_col] = option.value try: - idx,row = next(self.gen) + idx, row = next(self.gen) except StopIteration as e: self.out.clear_output() display(self.get_progress_bar(self.df.index[-1])) display(HTML("

    All Done

    ")) - display(HTML("
    Thanks for all the labeling, now try self.df to see the result
    ")) + display( + HTML("
    Thanks for all the labeling, now try self.df to see the result
    ")) return - self.show_func(idx,row) + self.show_func(idx, row) def __iter__(self): for idx, row in self.df.iterrows(): - if (row[self.result_col] is None) and (len(row[self.options_col]))>1: + if (row[self.result_col] is None) and (len(row[self.options_col])) > 1: yield idx, row def __call__(self) -> None: @@ -311,13 +320,13 @@ def show_func(self, idx, row) -> None: self.out.clear_output() with self.out: display( - VBox([ - self.get_progress_bar(idx), - HTML(self.show_callback(idx, row)), - self.button_box(idx, row[self.options_col]) - ])) + VBox([ + self.get_progress_bar(idx), + HTML(self.show_callback(idx, row)), + self.button_box(idx, row[self.options_col]) + ])) + -# Cell total_width = Layout(width="100%") @@ -380,6 +389,7 @@ class EditableDict(VBox): You can add item to the dictionary Each added item has a remove button to remove such item """ + def __init__(self, data_dict: Dict[str, Any] = dict(), pretty_json: bool = True): super().__init__([], layout=total_width) self.pretty_json = pretty_json @@ -436,7 +446,7 @@ def __setitem__(self, k, v): self.create_line(k, v) def __add__(self, kv): - for k,v in kv.items(): + for k, v in kv.items(): self.create_line(k, v) return self @@ -444,9 +454,9 @@ def get_data(self) -> Dict[str, Any]: """ Return the data of this dict """ - return dict((x.key,x.data) for x in self.children) + return dict((x.key, x.data) for x in self.children) + -# Cell class LivingStep: """ A step interactive for StepByStep @@ -493,7 +503,7 @@ def __init__( self.footer: Output = Output() self.create_widget() - def rerun(self,**kwargs): + def rerun(self, **kwargs): """ Rerun the current step function """ @@ -534,7 +544,7 @@ def create_widget(self) -> None: ) # assign action to first button first_btn: Button = list(self.progress_btns.values())[0] - first_btn.click: Callable = self.to_page_action(0) + first_btn.click = self.to_page_action(0) self.progress_bar = HBox(list(self.progress_btns.values())) # assemble the entire widget @@ -580,14 +590,14 @@ def __getitem__(self, page_id): self.current: int = page_id key: str = self.step_keys[page_id] step: LivingStep = self.steps[key] - self.title.value: str = f"

    Step {page_id+1}: {key}

    " + self.title.value = f"

    Step {page_id+1}: {key}

    " self.page_output.clear_output() with self.page_output: display(step.output) if key not in self.execute_cache: rt = step(progress=self, **self.kwargs) - if hasattr(rt,"keys"): + if hasattr(rt, "keys"): self.kwargs(rt) self.execute_cache[key] = True @@ -632,4 +642,4 @@ def show_footer(self, func: Callable): def wrapper(*args, **kwargs): with self.footer: return func(*args, **kwargs) - return wrapper \ No newline at end of file + return wrapper diff --git a/forgebox/wildtree.py b/forgebox/wildtree.py index 5b08309..cc0fe10 100644 --- a/forgebox/wildtree.py +++ b/forgebox/wildtree.py @@ -1,15 +1,13 @@ -# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/40_wild_tree_and_loss.ipynb (unless otherwise specified). - __all__ = ['cache', 'WildNode', 'WildEdge', 'WildTree', 'calc_weight', 'loss_package'] -# Cell + import pandas as pd import numpy as np from pathlib import Path from collections import Counter from typing import Callable, List, Dict -# Cell + def cache(f: Callable) -> Callable: """ cache for class property, use as decorator @@ -208,7 +206,7 @@ def __call__(self, a: str, b: str) -> pd.DataFrame: df['to_root'] = df.name.apply(lambda x:self[x].to_root) return df -# Cell + def calc_weight(x: np.array): """ Calculate the weight for BCELoss, diff --git a/nbs_hide/11_train.ipynb b/nbs_hide/11_train.ipynb deleted file mode 100644 index d2edc63..0000000 --- a/nbs_hide/11_train.ipynb +++ /dev/null @@ -1,989 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# PyTorch Train" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "# default_exp loops" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# export\n", - "from forgebox.loop import Loop,Event,method4all,StorageCore,ProgressBar,Tolerate" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "import torch" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "def create_event(event_name):\n", - " class ProductEvent(Event):pass\n", - " \n", - " ProductEvent.__name__=event_name\n", - " return ProductEvent\n", - "\n", - "def events(*event_names):\n", - " return tuple(list(map(create_event,event_names)))" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "layer:>>>e1" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "events(\"e1\",\"e2\")[0]()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loop layer e1 summary:\n", - "==================================================\n", - "🍰layer0.0\tlayer:>>>e1\n", - "\t[🐍func_name]\tafter_last_e1\n", - "\t[⛰doc]\t\n", - " Append new after_last callback for event:e1\n", - " Use this function as decorator\n", - " \n", - "\t[😝var]\tcls,f\n", - "\t[😜names]\tgetattr\n", - "\t...................................\n", - "\t[🐍func_name]\tbefore_1st_e1\n", - "\t[⛰doc]\t\n", - " Append new before_1st callback for event:e1\n", - " Use this function as decorator\n", - " \n", - "\t[😝var]\tcls,f\n", - "\t[😜names]\tgetattr\n", - "\t...................................\n", - "\t[🐍func_name]\ton_e1\n", - "\t[⛰doc]\t\n", - " Append new on callback for event:e1\n", - " Use this function as decorator\n", - " \n", - "\t[😝var]\tcls,f\n", - "\t[😜names]\tgetattr\n", - "\t...................................\n", - "--------------------------------------------------\n", - "==================================================\n", - "\n" - ] - } - ], - "source": [ - "l1.summary()" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "class DataLoop(Loop):\n", - " def __init__(self,dataloader=None):\n", - " super().__init__(iterable=dataloader)" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [], - "source": [ - "from types import MethodType" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [], - "source": [ - "class LoopStack:\n", - " @classmethod\n", - " def from_Loops(cls,*Loops):\n", - " cls.Loops = dict()\n", - " for L in Loops:\n", - " setattr(cls,L.__name__,L)\n", - " cls.Loops.update({L.__name__:L})\n", - " def init(self,iterable=[]):\n", - " last = iterable\n", - " for k,L in self.Loops.items():\n", - " layer = L(last) \n", - " last = layer\n", - " self.layer = last\n", - " \n", - " setattr(cls,\"__init__\",MethodType(init,cls))\n", - " return cls\n", - " \n", - " def __getattr__(self,k):\n", - " return getattr(self.layer,k)\n", - " \n", - " def __repr__(self):\n", - " return f\"LoopStack with\\n\\t\"+\"\\n\\t\".join(self.Loops.keys())" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [], - "source": [ - "STANDARD_TRAIN_PROCESS = events(\"PREPROCESS\",\"FORWARD\",\"CALC_LOSS\",\"BACKWARD\",\"OPTIMIZING\",\"METRICS\")\n", - "STANDARD_EVAL_PROCESS = events(\"PREPROCESS\",\"EVAL_SCOPE\",\"FORWARD\",\"CALC_LOSS\",\"METRICS\")" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [], - "source": [ - "TrainLoop = LoopStack.from_Loops(DataLoop,\n", - " ProgressBar,\n", - " Tolerate,\n", - " *STANDARD_TRAIN_PROCESS)" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [], - "source": [ - "train_loop = TrainLoop(range(100))" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "LoopStack with\n", - "\tDataLoop\n", - "\tProgressBar\n", - "\tTolerate\n", - "\tPREPROCESS\n", - "\tFORWARD\n", - "\tCALC_LOSS\n", - "\tBACKWARD\n", - "\tOPTIMIZING\n", - "\tMETRICS" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "train_loop" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "563a7cade71f4a3185eeb96b7084e93e", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "train_loop.run()" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loop layer opt_step summary:\n", - "==================================================\n", - "🍰layer0.0\tlayer:>>>DataLoop\n", - "--------------------------------------------------\n", - "🍰layer1.0\tlayer:>>>Progressb Bar\n", - "\t[🐍func_name]\tpgbar_data\n", - "\t[⛰doc]\t\n", - " update progress bar with python dictionary\n", - " data: python dictionary\n", - " \n", - "\t[😝var]\tself,data\n", - "\t[😜names]\tt,set_postfix\n", - "\t...................................\n", - "\t[🐍func_name]\tpgbar_description\n", - "\t[⛰doc]\t\n", - " update progress bar prefix with text string\n", - " \n", - "\t[😝var]\tself,text\n", - "\t[😜names]\tt,set_description_str\n", - "\t...................................\n", - "--------------------------------------------------\n", - "🍰layer2.0\tlayer:>>>Tolerate\n", - "\t[🐍func_name]\terror_list\n", - "\t[⛰doc]\t\n", - " A list of errors happend so far\n", - " \n", - "\t[😝var]\tself\n", - "\t[😜names]\terrors\n", - "\t...................................\n", - "--------------------------------------------------\n", - "🍰layer3.0\tlayer:>>>before_forward\n", - "\t[🐍func_name]\ton_before_forward\n", - "\t[⛰doc]\t\n", - " Excute callback for event:before_forward\n", - " \n", - "\t[😝var]\tself\n", - "\t[😜names]\t__call__\n", - "\t...................................\n", - "\t[🐍func_name]\tset_before_forward\n", - "\t[⛰doc]\t\n", - " Append new callback for event:before_forward\n", - " Use this function as decorator\n", - " \n", - "\t[😝var]\tself,f\n", - "\t[😜names]\ton\n", - "\t...................................\n", - "--------------------------------------------------\n", - "🍰layer4.0\tlayer:>>>forward\n", - "\t[🐍func_name]\ton_forward\n", - "\t[⛰doc]\t\n", - " Excute callback for event:forward\n", - " \n", - "\t[😝var]\tself\n", - "\t[😜names]\t__call__\n", - "\t...................................\n", - "\t[🐍func_name]\tset_forward\n", - "\t[⛰doc]\t\n", - " Append new callback for event:forward\n", - " Use this function as decorator\n", - " \n", - "\t[😝var]\tself,f\n", - "\t[😜names]\ton\n", - "\t...................................\n", - "--------------------------------------------------\n", - "🍰layer5.0\tlayer:>>>calc_loss\n", - "\t[🐍func_name]\ton_calc_loss\n", - "\t[⛰doc]\t\n", - " Excute callback for event:calc_loss\n", - " \n", - "\t[😝var]\tself\n", - "\t[😜names]\t__call__\n", - "\t...................................\n", - "\t[🐍func_name]\tset_calc_loss\n", - "\t[⛰doc]\t\n", - " Append new callback for event:calc_loss\n", - " Use this function as decorator\n", - " \n", - "\t[😝var]\tself,f\n", - "\t[😜names]\ton\n", - "\t...................................\n", - "--------------------------------------------------\n", - "🍰layer6.0\tlayer:>>>backward\n", - "\t[🐍func_name]\ton_backward\n", - "\t[⛰doc]\t\n", - " Excute callback for event:backward\n", - " \n", - "\t[😝var]\tself\n", - "\t[😜names]\t__call__\n", - "\t...................................\n", - "\t[🐍func_name]\tset_backward\n", - "\t[⛰doc]\t\n", - " Append new callback for event:backward\n", - " Use this function as decorator\n", - " \n", - "\t[😝var]\tself,f\n", - "\t[😜names]\ton\n", - "\t...................................\n", - "--------------------------------------------------\n", - "🍰layer7.0\tlayer:>>>opt_step\n", - "\t[🐍func_name]\ton_opt_step\n", - "\t[⛰doc]\t\n", - " Excute callback for event:opt_step\n", - " \n", - "\t[😝var]\tself\n", - "\t[😜names]\t__call__\n", - "\t...................................\n", - "\t[🐍func_name]\tset_opt_step\n", - "\t[⛰doc]\t\n", - " Append new callback for event:opt_step\n", - " Use this function as decorator\n", - " \n", - "\t[😝var]\tself,f\n", - "\t[😜names]\ton\n", - "\t...................................\n", - "--------------------------------------------------\n", - "==================================================\n", - "\n" - ] - } - ], - "source": [ - "train_loop.summary()" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "metadata": {}, - "outputs": [], - "source": [ - "@train_loop.layer.set_opt_step\n", - "def opt_step(self):\n", - " print(\"step\")" - ] - }, - { - "cell_type": "code", - "execution_count": 85, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "060a4c7f562b47849abc01e0b5597fb2", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(IntProgress(value=0), HTML(value='')))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "step\n", - "\n" - ] - } - ], - "source": [ - "train_loop.run()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.4" - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": true, - "toc_window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/settings.ini b/settings.ini index a58b086..f54a803 100644 --- a/settings.ini +++ b/settings.ini @@ -7,18 +7,15 @@ author = xiaochen(ray) zhang author_email = b2ray2c@gmail.com copyright = xiaochen(ray) zhang branch = master -version = 0.4.20 +version = 1.0.0 min_python = 3.6 +host = github audience = Developers language = English custom_sidebar = False license = apache2 status = 2 -nbs_path = nbs doc_path = docs -doc_host = https://raynardj.github.io -doc_baseurl = /forgebox/ -git_url = https://github.com/raynardj/forgebox/tree/master/ lib_path = forgebox -title = forgebox -host = github +title = ForgeBox +requirements = category>=0.1.0 jupyterlab_widgets ipywidgets pandas \ No newline at end of file diff --git a/setup.backup b/setup.backup deleted file mode 100644 index 40d12d2..0000000 --- a/setup.backup +++ /dev/null @@ -1,20 +0,0 @@ -from setuptools import setup -from setuptools import find_packages - -# data_files = [('etc', ['etc/forgebox.cfg'])] - -setup( - name="forgebox", - version="0.1.1", - author="raynardj", - author_email="raynard@rasenn.com", - description="Tools for managing machine learning", - packages = find_packages(), - include_package_data=True, - py_modules=['forgebox',], - # scripts = ['forge/bin/forge', 'forge/bin/forge_db',], - # package_data={'forge':['./forge/templates/*','./forge/static/*']}, - install_requires = [ - "tqdm>=4.25.0", - ], -) diff --git a/setup.py b/setup.py index 576fb6a..9364ca8 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,7 @@ -from pkg_resources import parse_version -from configparser import ConfigParser import setuptools +from configparser import ConfigParser +from pathlib import Path +from pkg_resources import parse_version assert parse_version(setuptools.__version__)>=parse_version('36.2') # note: all settings are in settings.ini; edit there, not here @@ -8,38 +9,64 @@ config.read('settings.ini') cfg = config['DEFAULT'] -cfg_keys = 'version description keywords author author_email'.split() -expected = cfg_keys + "lib_name user branch license status min_python audience language".split() -for o in expected: assert o in cfg, "missing expected setting: {}".format(o) -setup_cfg = {o:cfg[o] for o in cfg_keys} +cfg_keys = "version description keywords author author_email".split() +expected = ( + cfg_keys + + "lib_name user branch license status min_python audience language".split() +) + +statuses = [ + "1 - Planning", + "2 - Pre-Alpha", + "3 - Alpha", + "4 - Beta", + "5 - Production/Stable", + "6 - Mature", + "7 - Inactive", +] + +py_versions = ( + "2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8".split() +) + +for exp in expected: + assert exp in cfg, f"missing expected setting: {exp}" +setup_cfg = {k: cfg[k] for k in cfg_keys} + +requirements = cfg.get("requirements", "").split() +min_python = cfg["min_python"] +comp_version = py_versions[py_versions.index(min_python):] -licenses = { - 'apache2': ('Apache Software License 2.0','OSI Approved :: Apache Software License'), -} -statuses = [ '1 - Planning', '2 - Pre-Alpha', '3 - Alpha', - '4 - Beta', '5 - Production/Stable', '6 - Mature', '7 - Inactive' ] -py_versions = '2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8'.split() +with open('forgebox/__init__.py', 'r') as f: + lines = f.readlines() -requirements = cfg.get('requirements','').split() -lic = licenses[cfg['license']] -min_python = cfg['min_python'] +with open('forgebox/__init__.py', 'w') as f: + version = cfg["version"] + first_line = f'__version__ = "{version}"\n' + f.write(first_line) + for line in lines[1:]: + f.write(line) setuptools.setup( - name = cfg['lib_name'], - license = lic[0], - classifiers = [ - 'Development Status :: ' + statuses[int(cfg['status'])], - 'Intended Audience :: ' + cfg['audience'].title(), - 'License :: ' + lic[1], - 'Natural Language :: ' + cfg['language'].title(), - ] + ['Programming Language :: Python :: '+o for o in py_versions[py_versions.index(min_python):]], - url = 'https://github.com/{}/{}'.format(cfg['user'],cfg['lib_name']), - packages = setuptools.find_packages(), - include_package_data = True, - install_requires = requirements, - python_requires = '>=' + cfg['min_python'], - long_description = open('README.md').read(), - long_description_content_type = 'text/markdown', - zip_safe = False, - entry_points = { 'console_scripts': cfg.get('console_scripts','').split() }, - **setup_cfg) \ No newline at end of file + name=cfg["lib_name"], + license='GPLv3+', + version=cfg["version"], + classifiers=[ + "Development Status :: " + statuses[int(cfg["status"])], + "Intended Audience :: " + cfg["audience"].title(), + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Natural Language :: " + cfg["language"].title(), + ] + + [f"Programming Language :: Python :: {v}" for v in comp_version], + url=f"https://github.com/{cfg['user']}/forgebox", + packages=setuptools.find_packages(), + include_package_data=True, + install_requires=requirements, + python_requires=">=" + cfg["min_python"], + long_description=Path("README.md").read_text(encoding="utf-8"), + long_description_content_type="text/markdown", + project_urls={ + "Documentation": "https://github/raynardj/forgebox/", + "Tracker": "https://github.com/raynardj/forgebox/issues", + }, +) \ No newline at end of file diff --git a/test/import_test.py b/test/import_test.py new file mode 100644 index 0000000..ae3fb8b --- /dev/null +++ b/test/import_test.py @@ -0,0 +1,11 @@ +def test_import_things(): + from forgebox.imports import ( + pd, np, json + ) + assert hasattr(pd.DataFrame, "split") + assert hasattr(pd.DataFrame, "paginate") + +def test_import_category(): + from forgebox.category import ( + Category, MultiCategory, FastCategory, FastMultiCategory + ) \ No newline at end of file diff --git a/test/pipeline_test.py b/test/pipeline_test.py new file mode 100644 index 0000000..e5799b0 --- /dev/null +++ b/test/pipeline_test.py @@ -0,0 +1,87 @@ +from forgebox.cosine import CosineSearch +from forgebox.config import Config +from forgebox.files import file_detail +from forgebox.batcher import Batcher +from forgebox.imports import * + + +def test_batecher(): + batcher = Batcher([1, 2, 3, 4, 5], batch_size=2) + batches = list(batcher) + assert len(batches) == 3 + assert batches[0] == [1, 2] + assert batches[1] == [3, 4] + assert batches[2] == [5] + assert batcher.one_batch() == [1, 2] + + +def test_vc(): + df = pd.DataFrame(dict( + col1=["a", "b", "c", "a", "b", "c"], + col2=["a", "b", "c", "a", "b", "c"], + col3=["a", "b", "c", "a", "b", "c"] + )) + vc = df.vc("col1") + assert vc.iloc[0, 0] == 2 + + +def test_split(): + df = pd.DataFrame(dict( + col1=list(range(50)))) + train_df, valid_df = df.split() + assert len(train_df) > len(valid_df) + train_df, valid_df = df.split(.8) + assert len(train_df) < len(valid_df) + + +def test_column_order(): + df = pd.DataFrame(dict( + col1=["a", "b", "c", "a", "b", "c"], + col2=["a", "b", "c", "a", "b", "c"], + col3=["a", "b", "c", "a", "b", "c"] + )) + df = df.column_order("col2", "col1", "col3") + assert df.columns.tolist() == ["col2", "col1", "col3"] + + +def test_get_files(): + import os + p = Path(os.getcwd()) + test_dir = p/"test_dir" + test_dir.mkdir(exist_ok=True) + test_dir.joinpath("test_file.txt").touch() + test_dir.joinpath("test_file2.txt").touch() + test_dir.joinpath("test_file3.txt").touch() + test_dir.joinpath("test_file4.txt").touch() + df = file_detail(test_dir) + assert len(df) == 4 + assert df.file_type.iloc[0] == "txt" + assert df.file_type.iloc[1] == "txt" + assert df.file_type.iloc[2] == "txt" + assert df.file_type.iloc[3] == "txt" + assert df.parent.iloc[0] == "test_dir" + + # clear test_dir + + for file in df.path: + os.remove(file) + test_dir.rmdir() + + +def test_config(): + config = Config(a=1, b=2, c=[1, "2"]) + config.save("test_config.json") + config2 = Config.load("test_config.json") + assert config2.a == 1 + assert config2.b == 2 + assert config2.c == [1, "2"] + + +def test_cosine_search(): + base = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + vec = np.array([4, 5, 2]) + vec2 = np.array([2, 9, 9]) + cos = CosineSearch(base) + assert (cos(vec) == [2, 1, 0]).all() + assert (cos(vec2) == [0, 1, 2]).all() + assert (cos.search(vec) == [2, 1 ,0]).all()