From e9da251beefead894a60d59eb8a6b5702559412d Mon Sep 17 00:00:00 2001 From: MarsBarLee <46167686+MarsBarLee@users.noreply.github.com> Date: Tue, 7 Feb 2023 16:18:13 -0500 Subject: [PATCH 1/8] Add files --- ...on-data-analysis-productivity-framework.md | 247 ++++++++++++++++++ ...f0a567ee713d1392bab6d8fef07bbe9777c033.png | Bin 0 -> 30180 bytes ...a51ad71e1a32140f3e47e71145e6a67d061750.png | Bin 0 -> 16104 bytes ...2b7c1311b137ea2d1bfd6e7715369df26b2570.png | Bin 0 -> 8497 bytes 4 files changed, 247 insertions(+) create mode 100644 apps/labs/posts/ibis-python-data-analysis-productivity-framework.md create mode 100644 apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/70f0a567ee713d1392bab6d8fef07bbe9777c033.png create mode 100644 apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/a0a51ad71e1a32140f3e47e71145e6a67d061750.png create mode 100644 apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/e62b7c1311b137ea2d1bfd6e7715369df26b2570.png diff --git a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md new file mode 100644 index 000000000..a961d310b --- /dev/null +++ b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md @@ -0,0 +1,247 @@ +--- +title: "Ibis: Python data analysis productivity framework" +author: ivan-ogasawara +published: July 9, 2019 +description: '' +category: [PyData ecosystem] +featuredImage: + src: /posts/hello-world-post/featured.png + alt: 'Excellent alt-text describing the featured image' +hero: + imageSrc: /posts/hello-world-post/hero.jpeg + imageAlt: 'Excellent alt-text describing the hero image' +--- + +Ibis is a library pretty useful on data analysis tasks that provides a +pandas-like API that allows operations like create filter, add columns, +apply math operations etc in a `lazy` mode so all the operations are +just registered in memory but not executed and when you want to get the +result of the expression you created, Ibis compiles that and makes a +request to the remote server (remote storage and execution systems like +Hadoop components or SQL databases). Its goal is to simplify analytical +workflows and make you more productive. + +Ibis was created by [Wes McKinney](https://github.com/wesm) and is +mainly maintained by [Phillip Cloud](https://github.com/cpcloud) and +[Krisztián Szűcs](https://github.com/kszucs). Also, recently, I was +invited to become a maintainer of the Ibis repository! + +Maybe you are thinking: \"why should I use Ibis?\". Well, if you have +any of the following issues, probably you should consider using Ibis in +your analytical workflow! + +- if you need to get data from a SQL database but you don't know much + about SQL \... +- if you create SQL statements manually using string and have a lot of + `IF`'s in your code that compose specific parts of your SQL code + (it could be pretty hard to maintain and it will makes your code + pretty ugly) \... +- if you need to handle data with a big volume \... + +If you want to learn more about ibis consider taking a look at these +tutorials: + +- + +Do you want to watch some interesting video about Ibis? Check this out: + +- + +**Now, let's check out some work developed here at Quansight in the +last months!** + +During the last months **OmniSci** and **Quansight** were working +together to add a backend to Ibis for **OmniSciDB** (formerly MapD +Core)! In a few words, OmniSciDB is an in-memory, column store, SQL +relational database designed from the ground up to run on GPUs. If you +don't know yet this amazing database, I invite you to [check it +out](https://omnisci.com). + +The implementation of this new backend also resulted in the creation of +new expressions/operators on Ibis core, such as: + +- GeoSpatial data types and operations +- Trigonometric operations +- Some statistcal operations + +First, let's connect to a *OmniSciDB* and play with this new features! + +``` python +# install the dependencies if you need! +# !conda install -y ibis-framework=1.1.0 pyarrow pymapd vega geopandas geoalchemy2 shapely matplotlib --force-reinstall +``` + +``` python +import ibis +from matplotlib import pyplot as plt + +print('ibis:', ibis.__version__) +``` + + ibis: 1.2.0+7.g3afa8b0d + +``` python +# metis.mapd.com is used in some OmniSci docs +# but maybe you want to install your own OmniSciDB instance +# you can take a look into installation section at +# https://www.omnisci.com/docs/latest/ +# also you maybe want to check the omniscidb-cpu conda package +# conda install -c conda-forge omniscidb-cpu +# if you need any help, feel free to open an issue at +# https://github.com/conda-forge/omniscidb-cpu-feedstock/ +omniscidb_cli = ibis.mapd.connect( + host='metis.mapd.com', + user='mapd', + password='HyperInteractive', + port=443, + database='mapd', + protocol='https' +) +``` + +### GeoSpatial features + +You need to handle geospatial data in a esier way? + +Let's take a look inside `zipcodes_2017` table! + +Well, currently `omniscidb` backend doesn't support `geopandas` output, +so let's use a workaround for that! It should be implemented into +`omniscidb` backend soon! (see: +[gist-code](https://gist.githubusercontent.com/xmnlab/587dd1bde44850f3117a1087ed3f0f28/raw/0750400db90cf97319a91aa514648c31ad4ace45/omniscidb_geopandas_output.py)) + +``` python +gist_url = 'https://gist.githubusercontent.com/xmnlab/587dd1bde44850f3117a1087ed3f0f28/raw/0750400db90cf97319a91aa514648c31ad4ace45/omniscidb_geopandas_output.py' +!wget {gist_url} -O omniscidb_geopandas_output.py +``` + + --2019-07-05 11:31:57-- https://gist.githubusercontent.com/xmnlab/587dd1bde44850f3117a1087ed3f0f28/raw/0750400db90cf97319a91aa514648c31ad4ace45/omniscidb_geopandas_output.py + Resolviendo gist.githubusercontent.com (gist.githubusercontent.com)... 151.101.48.133 + Conectando con gist.githubusercontent.com (gist.githubusercontent.com)[151.101.48.133]:443... conectado. + Petición HTTP enviada, esperando respuesta... 200 OK + Longitud: 1874 (1,8K) [text/plain] + Guardando como: “omniscidb_geopandas_output.py” + + omniscidb_geopandas 100%[===================>] 1,83K --.-KB/s en 0s + + 2019-07-05 11:31:57 (70,1 MB/s) - “omniscidb_geopandas_output.py” guardado [1874/1874] + +``` python +# workaround to use geopandas output +from omniscidb_geopandas_output import enable_geopandas_output +enable_geopandas_output(omniscidb_cli) +``` + +``` python +t = omniscidb_cli.table('zipcodes_2017') +display(t) +``` + +![A DatabaseTable with its data types](a0a51ad71e1a32140f3e47e71145e6a67d061750.png) + +``` python +print('# rows:', t.count().execute()) +``` + + # rows: 33144 + +This table has \~33k rows. For this example, let's use just the first +1k rows. + +``` python +expr = t[t.omnisci_geo].head(1000) +df = expr.execute() +``` + +Instead of getting all rows from the database and get from that the +first 1000 rows, Ibis will prepare a SQL statement to get just the first +1000 rows! So it reduces the memory consuming to just the data you need! + +This is what Ibis will request to the database: + +``` python +print(expr.compile()) +``` + + SELECT "omnisci_geo" + FROM zipcodes_2017 + LIMIT 1000 + +Of course geospatial data reading as text wouldn't be useful, so let's +plot the result! + +**Remember: we are using geopandas here!** + +``` python +# let's add some custom style :) +style_kwds = { + 'linewidth': 2, + 'markersize': 2, + 'facecolor': 'red', + 'edgecolor': 'red' +} + +df['omnisci_geo'].iloc[::3].plot(**style_kwds) +plt.show() +``` + +![A scatterplot graph clustered in the upper right corner. It is clusetered -120 to 80 on the X axis and 40-60 in the Y axis.](e62b7c1311b137ea2d1bfd6e7715369df26b2570.png) + +### Trigonometric operations + +Currently the OmniSciDB backend supports the follow trigonometric +operations: `acos`, `asin`, `atan`, `atan2`, `cos`, `cot`, `sin`, `tan`. + +Let's check an example using a `sin` operation over `rowid` from +`zipcodes_2017`. + +``` python +# if you want to use a SQL statement try`sql` method! +t = omniscidb_cli.sql('select rowid from zipcodes_2017') + +expr = t[t.rowid, t.rowid.sin().name('rowid_sin')].sort_by('rowid').head(100) +expr.execute().rowid_sin.plot() +plt.show() +``` + +![A sine wave plot that repeats many times, the high points at 1,-- and -1.00. The X axis is 0 to 80.](70f0a567ee713d1392bab6d8fef07bbe9777c033.png) + +### Some statistical operations + +The OmniSciDB Ibis backend also implements some statistical operations, +such as: `Correlation (corr)`, `Standard Deviation (stddev)`, +`Variance (var)` and `Covariance (cov)`. + +Let's check a pretty simple example: if there is any correlation in +this dataset between `per capita income` and `education`. + +``` python +t = omniscidb_cli.table('demo_vote_clean') +# remove some conflictives fields: 'TYPE', 'NAME', 'COUNTY' field +fields = [name for name in t.schema().names if name not in ('TYPE', 'NAME', 'COUNTY')] +t = t[fields].distinct() +t.PerCapitaIncome.corr(t.Education).execute() +``` + + 0.7212061029308654 + +The result `~0.72` means that `Per Capita Income` and `Education` has a +positive correlation in this dataset. + +### Conclusions + +Ibis is a cool library that can help you in your data analysis tasks. If +you already use pandas, it will be pretty easy to add Ibis in your +workflow! + +So \... + +- Are you excited to use Ibis? [Try it out + now](https://docs.ibis-project.org/getting-started.html)! +- Have you already used Ibis? Reach out to me, + , and share your experience! +- Are you interested in contributing to Ibis? Check the [good first + issues](https://github.com/ibis-project/ibis/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) + label on GitHub! +- Do you want to add new features and want to fund Ibis? Contact us at + diff --git a/apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/70f0a567ee713d1392bab6d8fef07bbe9777c033.png b/apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/70f0a567ee713d1392bab6d8fef07bbe9777c033.png new file mode 100644 index 0000000000000000000000000000000000000000..5fb3c95d4ee6fe7d3cb33d95c36d2c40bd5efb3b GIT binary patch literal 30180 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 BpOXLp literal 0 HcmV?d00001 diff --git a/apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/a0a51ad71e1a32140f3e47e71145e6a67d061750.png b/apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/a0a51ad71e1a32140f3e47e71145e6a67d061750.png new file mode 100644 index 0000000000000000000000000000000000000000..df5e88bebc75a0191ee829f1182edd06498a3b90 GIT binary patch literal 16104 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 literal 0 HcmV?d00001 From 1085fe832cca644d07799c9f90ee4adfa4f3ea98 Mon Sep 17 00:00:00 2001 From: MarsBarLee <46167686+MarsBarLee@users.noreply.github.com> Date: Wed, 8 Feb 2023 13:19:14 -0500 Subject: [PATCH 2/8] Update description and links --- .../ibis-python-data-analysis-productivity-framework.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md index a961d310b..f096c9952 100644 --- a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md +++ b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md @@ -2,7 +2,7 @@ title: "Ibis: Python data analysis productivity framework" author: ivan-ogasawara published: July 9, 2019 -description: '' +description: 'During the last months OmniSci and Quansight were working together to add a backend to Ibis for OmniSciDB (formerly MapD Core)The implementation of this new backend also resulted in the creation of new expressions/operators on Ibis core, such as GeoSpatial data types and operations, trigonometric operations and Ssome statistcal operations.' category: [PyData ecosystem] featuredImage: src: /posts/hello-world-post/featured.png @@ -41,11 +41,11 @@ your analytical workflow! If you want to learn more about ibis consider taking a look at these tutorials: -- +- [https://docs.ibis-project.org/tutorial.html](https://docs.ibis-project.org/tutorial.html) Do you want to watch some interesting video about Ibis? Check this out: -- +- [https://www.youtube.com/embed/8Tzh42mQjrw?start=1625](https://www.youtube.com/embed/8Tzh42mQjrw?start=1625) **Now, let's check out some work developed here at Quansight in the last months!** From acd9403d7eca52786d336045688038d48e6bea0c Mon Sep 17 00:00:00 2001 From: MarsBarLee <46167686+MarsBarLee@users.noreply.github.com> Date: Wed, 8 Feb 2023 13:24:43 -0500 Subject: [PATCH 3/8] Update link formatting --- .../posts/ibis-python-data-analysis-productivity-framework.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md index f096c9952..c28186828 100644 --- a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md +++ b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md @@ -239,7 +239,7 @@ So \... - Are you excited to use Ibis? [Try it out now](https://docs.ibis-project.org/getting-started.html)! - Have you already used Ibis? Reach out to me, - , and share your experience! + [ivan.ogasawara@quansight.com](ivan.ogasawara@quansight.com), and share your experience! - Are you interested in contributing to Ibis? Check the [good first issues](https://github.com/ibis-project/ibis/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) label on GitHub! From 4053b5d394be7c44537804de9e1a8e9dc45b5073 Mon Sep 17 00:00:00 2001 From: MarsBarLee <46167686+MarsBarLee@users.noreply.github.com> Date: Wed, 8 Feb 2023 13:27:00 -0500 Subject: [PATCH 4/8] Update link formatting --- .../posts/ibis-python-data-analysis-productivity-framework.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md index c28186828..9010d588e 100644 --- a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md +++ b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md @@ -244,4 +244,4 @@ So \... issues](https://github.com/ibis-project/ibis/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) label on GitHub! - Do you want to add new features and want to fund Ibis? Contact us at - + (info@quansight.com)[info@quansight.com] From 2875adb38056aa842c617933f0f4cdd311c4796f Mon Sep 17 00:00:00 2001 From: MarsBarLee <46167686+MarsBarLee@users.noreply.github.com> Date: Wed, 8 Feb 2023 13:47:13 -0500 Subject: [PATCH 5/8] Update hero and feature image --- .../ibis-python-data-analysis-productivity-framework.md | 8 ++++---- .../blog_feature_var2.svg | 1 + .../blog_hero_var1.svg | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/blog_feature_var2.svg create mode 100644 apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/blog_hero_var1.svg diff --git a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md index 9010d588e..88c60b086 100644 --- a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md +++ b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md @@ -5,11 +5,11 @@ published: July 9, 2019 description: 'During the last months OmniSci and Quansight were working together to add a backend to Ibis for OmniSciDB (formerly MapD Core)The implementation of this new backend also resulted in the creation of new expressions/operators on Ibis core, such as GeoSpatial data types and operations, trigonometric operations and Ssome statistcal operations.' category: [PyData ecosystem] featuredImage: - src: /posts/hello-world-post/featured.png - alt: 'Excellent alt-text describing the featured image' + src: /posts/ibis-an-idiomatic-flavor-of-sql-for-python-programmers/blog_feature_var2.svg + alt: 'An illustration of a brown and a white hand coming towards each other to pass a business card with the logo of Quansight Labs.' hero: - imageSrc: /posts/hello-world-post/hero.jpeg - imageAlt: 'Excellent alt-text describing the hero image' + imageSrc: /posts/ibis-an-idiomatic-flavor-of-sql-for-python-programmers/blog_hero_var1.svg + imageAlt: 'An illustration of a brown hand holding up a microphone, with some graphical elements highlighting the top of the microphone.' --- Ibis is a library pretty useful on data analysis tasks that provides a diff --git a/apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/blog_feature_var2.svg b/apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/blog_feature_var2.svg new file mode 100644 index 000000000..b7533414b --- /dev/null +++ b/apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/blog_feature_var2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/blog_hero_var1.svg b/apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/blog_hero_var1.svg new file mode 100644 index 000000000..87cda4aa2 --- /dev/null +++ b/apps/labs/public/posts/ibis-python-data-analysis-productivity-framework/blog_hero_var1.svg @@ -0,0 +1 @@ + \ No newline at end of file From 79bf5c4fdb85e3534a727fad3e37c4eafb3f7be8 Mon Sep 17 00:00:00 2001 From: MarsBarLee <46167686+MarsBarLee@users.noreply.github.com> Date: Thu, 9 Feb 2023 10:12:09 -0500 Subject: [PATCH 6/8] Update file paths --- .../posts/ibis-python-data-analysis-productivity-framework.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md index 88c60b086..da3f7fa62 100644 --- a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md +++ b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md @@ -5,10 +5,10 @@ published: July 9, 2019 description: 'During the last months OmniSci and Quansight were working together to add a backend to Ibis for OmniSciDB (formerly MapD Core)The implementation of this new backend also resulted in the creation of new expressions/operators on Ibis core, such as GeoSpatial data types and operations, trigonometric operations and Ssome statistcal operations.' category: [PyData ecosystem] featuredImage: - src: /posts/ibis-an-idiomatic-flavor-of-sql-for-python-programmers/blog_feature_var2.svg + src: /posts/ibis-python-data-analysis-productivity-framework/blog_feature_var2.svg alt: 'An illustration of a brown and a white hand coming towards each other to pass a business card with the logo of Quansight Labs.' hero: - imageSrc: /posts/ibis-an-idiomatic-flavor-of-sql-for-python-programmers/blog_hero_var1.svg + imageSrc: /posts/ibis-python-data-analysis-productivity-framework/blog_hero_var1.svg imageAlt: 'An illustration of a brown hand holding up a microphone, with some graphical elements highlighting the top of the microphone.' --- From 8babdffd2bc5b8a51a5b03e7cb3ee8377df37bde Mon Sep 17 00:00:00 2001 From: MarsBarLee <46167686+MarsBarLee@users.noreply.github.com> Date: Thu, 9 Feb 2023 10:22:02 -0500 Subject: [PATCH 7/8] Update image file paths --- .../ibis-python-data-analysis-productivity-framework.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md index da3f7fa62..ec2604bf5 100644 --- a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md +++ b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md @@ -137,7 +137,7 @@ t = omniscidb_cli.table('zipcodes_2017') display(t) ``` -![A DatabaseTable with its data types](a0a51ad71e1a32140f3e47e71145e6a67d061750.png) +![A DatabaseTable with its data types](/posts/ibis-python-data-analysis-productivity-framework/a0a51ad71e1a32140f3e47e71145e6a67d061750.png) ``` python print('# rows:', t.count().execute()) @@ -185,7 +185,7 @@ df['omnisci_geo'].iloc[::3].plot(**style_kwds) plt.show() ``` -![A scatterplot graph clustered in the upper right corner. It is clusetered -120 to 80 on the X axis and 40-60 in the Y axis.](e62b7c1311b137ea2d1bfd6e7715369df26b2570.png) +![A scatterplot graph clustered in the upper right corner. It is clusetered -120 to 80 on the X axis and 40-60 in the Y axis.](/posts/ibis-python-data-analysis-productivity-framework/e62b7c1311b137ea2d1bfd6e7715369df26b2570.png) ### Trigonometric operations @@ -204,7 +204,7 @@ expr.execute().rowid_sin.plot() plt.show() ``` -![A sine wave plot that repeats many times, the high points at 1,-- and -1.00. The X axis is 0 to 80.](70f0a567ee713d1392bab6d8fef07bbe9777c033.png) +![A sine wave plot that repeats many times, the high points at 1,-- and -1.00. The X axis is 0 to 80.](/posts/ibis-python-data-analysis-productivity-framework/70f0a567ee713d1392bab6d8fef07bbe9777c033.png) ### Some statistical operations From 8a47592ee8c8c9f424dd5002ea0813e4bfd1d036 Mon Sep 17 00:00:00 2001 From: MarsBarLee <46167686+MarsBarLee@users.noreply.github.com> Date: Thu, 9 Feb 2023 10:30:44 -0500 Subject: [PATCH 8/8] Add line break --- .../posts/ibis-python-data-analysis-productivity-framework.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md index ec2604bf5..0af14fb57 100644 --- a/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md +++ b/apps/labs/posts/ibis-python-data-analysis-productivity-framework.md @@ -115,7 +115,8 @@ gist_url = 'https://gist.githubusercontent.com/xmnlab/587dd1bde44850f3117a1087ed !wget {gist_url} -O omniscidb_geopandas_output.py ``` - --2019-07-05 11:31:57-- https://gist.githubusercontent.com/xmnlab/587dd1bde44850f3117a1087ed3f0f28/raw/0750400db90cf97319a91aa514648c31ad4ace45/omniscidb_geopandas_output.py + --2019-07-05 11:31:57-- [https://gist.githubusercontent.com/xmnlab/587dd1bde44850f3117a1087ed3f0f28/raw/0750400 + db90cf97319a91aa514648c31ad4ace45/omniscidb_geopandas_output.py](https://gist.githubusercontent.com/xmnlab/587dd1bde44850f3117a1087ed3f0f28/raw/0750400db90cf97319a91aa514648c31ad4ace45/omniscidb_geopandas_output.py) Resolviendo gist.githubusercontent.com (gist.githubusercontent.com)... 151.101.48.133 Conectando con gist.githubusercontent.com (gist.githubusercontent.com)[151.101.48.133]:443... conectado. Petición HTTP enviada, esperando respuesta... 200 OK