├── .gitignore ├── static ├── favicon.ico ├── favicon.png ├── assets │ ├── 04 │ │ ├── misc.jpg │ │ ├── signed.jpg │ │ ├── spotify.png │ │ ├── unsigned.jpg │ │ ├── categories.jpg │ │ ├── chart-types.png │ │ ├── pie-chart.jpeg │ │ ├── unsigned-2d.jpg │ │ ├── landscape-colors.png │ │ ├── technology-stocks.png │ │ ├── top2500feelings.png │ │ ├── grammar-of-graphics.png │ │ ├── Playfair_TimeSeries-2.png │ │ └── sphx_glr_anatomy_001.webp │ ├── 03 │ │ ├── flat_2d@1x.png │ │ ├── 2d_with_strides@1x.png │ │ └── flat_with_strides@1x.png │ ├── general │ │ ├── EnVivo@1x.png │ │ ├── GitHub@1x.png │ │ ├── Sharp@1x.png │ │ ├── Twitch@1x.png │ │ ├── Discord@1x.png │ │ ├── Twitter@1x.png │ │ └── YouTube@1x.png │ └── 02 │ │ ├── vector-tensor-matriz.jpg │ │ ├── filip-gielda-VPavA7BBxK0-unsplash.jpg │ │ ├── alfred-kenneally-UsgLeLorRuM-unsplash.jpg │ │ └── NumPy.svg ├── favicon-16x16.png ├── favicon-32x32.png ├── mstile-150x150.png ├── apple-touch-icon.png ├── images │ └── site │ │ ├── git.png │ │ ├── home.png │ │ ├── link.png │ │ ├── mail.png │ │ ├── print.png │ │ ├── reply.png │ │ ├── attach.png │ │ ├── console.png │ │ ├── create.png │ │ ├── events.png │ │ ├── forward.png │ │ ├── github.png │ │ ├── ideone.png │ │ ├── retweet.png │ │ ├── spritesheet │ │ ├── twitter.png │ │ ├── warning.png │ │ ├── youtube.png │ │ ├── backwards.png │ │ ├── clipboard.png │ │ ├── comments.png │ │ ├── download.png │ │ ├── feedback.png │ │ ├── ideone.sketch │ │ ├── more-tags.png │ │ ├── favicon@260w.png │ │ ├── footer-dots.png │ │ ├── spritesheet.png │ │ ├── warning-big.png │ │ ├── youtube-big.png │ │ ├── header-detail.png │ │ ├── forward_disabled.png │ │ ├── line-number-body.png │ │ ├── line-number-foot.png │ │ ├── line-number-head.png │ │ ├── title-panel-dots.png │ │ └── backwards_disabled.png ├── android-chrome-192x192.png ├── android-chrome-256x256.png ├── android-chrome-384x384.png ├── discord │ └── index.html ├── browserconfig.xml ├── site.webmanifest ├── safari-pinned-tab.svg └── js │ └── main.js ├── .gitmodules ├── Makefile ├── templates ├── home.html ├── includes │ ├── sidebar │ │ ├── google-translate.html │ │ ├── tag-list.html │ │ ├── category-list.html │ │ ├── archive-list.html │ │ ├── common-list.html │ │ └── article-menu.html │ ├── views │ │ ├── article.html │ │ ├── site-brand.html │ │ ├── post-item.html │ │ ├── segments.html │ │ ├── paginator.html │ │ ├── footer.html │ │ ├── post-header.html │ │ ├── banner.html │ │ ├── pagination.html │ │ └── header.html │ ├── functions │ │ ├── get_tags.html │ │ ├── get_categories.html │ │ ├── log.html │ │ ├── get_datetimes.html │ │ ├── get_article_words.html │ │ └── get_value.html │ ├── extensions │ │ ├── mathjax.html │ │ ├── favicon.html │ │ ├── geopattern.html │ │ ├── comments │ │ │ ├── gitment.html │ │ │ └── disqus.html │ │ ├── trianglify.html │ │ ├── google-analytics.html │ │ ├── hashlocate.html │ │ ├── seo.html │ │ ├── code-highlight.html │ │ └── theme-toggle.html │ ├── functions.html │ └── head.html ├── about.html ├── articles.html ├── framework.html ├── categories.html ├── archives.html ├── 404.html ├── tags.html ├── default.html ├── book.html ├── post.html └── video.html ├── content ├── posts │ ├── tv │ │ ├── 2019-03-03-por-fin-de-vuelta.md │ │ ├── 2017-09-06-escuela.md │ │ ├── 2018-08-21-2048-seguidores.md │ │ ├── 2019-03-11-machine-learning.md │ │ ├── 2017-03-14-pruebas-unitarias-vs.md │ │ ├── 2019-04-15-overfitting-underfitting.md │ │ ├── 2019-05-27-svm-explanation.md │ │ ├── 2019-04-01-regresion-lineal.md │ │ ├── 2017-06-27-implementacion-mvc.md │ │ ├── 2019-03-18-entornos-virtuales.md │ │ ├── 2019-04-10-numpy-pandas-parte-1.md │ │ ├── 2019-04-10-numpy-pandas-parte-2.md │ │ ├── 2018-08-14-neo4j.md │ │ ├── 2019-04-29-train-test-validate-split.md │ │ ├── 2017-12-22-escuela-otra-vez.md │ │ ├── 2016-12-06-subiendo-github.md │ │ ├── 2016-04-18-hola-mundo.md │ │ ├── 2017-07-11-implementacion-orm.md │ │ ├── 2016-07-13-sal-sintactica.md │ │ ├── 2017-08-15-mis-libros.md │ │ ├── 2016-07-20-first-class-citizens.md │ │ ├── 2018-01-19-sobre-youtube.md │ │ ├── 2017-11-27-memoizacion.md │ │ ├── 2016-09-26-martillo-dorado.md │ │ ├── 2018-03-20-programar-ingles.md │ │ ├── 2018-03-11-algoritmos-voraces.md │ │ ├── 2017-05-16-autorizacion-autenticacion.md │ │ ├── 2017-02-14-apis.md │ │ ├── 2016-04-18-ideone.md │ │ ├── 2016-08-10-programar-con-estilo.md │ │ ├── 2017-07-25-package-manager.md │ │ ├── 2017-12-11-expresiones-lambda.md │ │ ├── 2018-06-12-big-data.md │ │ ├── 2017-12-18-jupyter-notebooks.md │ │ ├── 2018-01-27-dormir-programar.md │ │ └── 2018-06-19-text-as-data.md │ ├── 2015-07-18-hello-world.md │ ├── 2015-11-02-xamarin-forms-mvvm-21-nov-2015.md │ ├── 2015-07-11-hola-mundo.md │ ├── 2016-06-02-mobile-c-sharp-workshop-17-oct-2016.md │ ├── 2015-10-19-mobile-c-sharp-workshop-17-oct-2015.md │ ├── 2015-10-22-arreglos-en-c-sharp-parte-2.md │ ├── 2015-07-12-bubble-display-netduino-plus-2.md │ ├── 2015-10-23-arreglos-en-c-sharp-parte-3.md │ ├── 2015-09-16-creando-propios-alias.md │ ├── 2015-11-16-code-organization-visual-studio.md │ ├── 2015-10-05-tipos-dato-c-sharp.md │ ├── 2015-11-16-organizacion-codigo-visual-studio.md │ ├── 2015-08-21-string-vs-system-string-es.md │ ├── 2015-12-16-ser-xamarin-student-partner.md │ ├── 2017-01-02-metas-blog-2017.md │ ├── 2016-06-02-meetup-1-junio-2016.md │ ├── 2015-08-15-importance-of-coding-with-style.md │ ├── 2015-12-09-c-sharp-juegos.md │ └── 2015-11-02-que-son-portable-class-library.md └── pages │ ├── about.md │ └── acerca-de.md ├── site.yml ├── .github └── workflows │ └── main.yml └── .liquidrc /.gitignore: -------------------------------------------------------------------------------- 1 | _site/* 2 | .DS_Store -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/favicon.ico -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/favicon.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lockdown"] 2 | path = lockdown 3 | url = git@github.com:lockdownblog/lockdown.git 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | run: 2 | dotnet run --project ./lockdown/Lockdown/Lockdown.csproj -- run --root . --output _site 3 | -------------------------------------------------------------------------------- /static/assets/04/misc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/misc.jpg -------------------------------------------------------------------------------- /static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/favicon-16x16.png -------------------------------------------------------------------------------- /static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/favicon-32x32.png -------------------------------------------------------------------------------- /static/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/mstile-150x150.png -------------------------------------------------------------------------------- /static/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/apple-touch-icon.png -------------------------------------------------------------------------------- /static/assets/04/signed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/signed.jpg -------------------------------------------------------------------------------- /static/assets/04/spotify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/spotify.png -------------------------------------------------------------------------------- /static/images/site/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/git.png -------------------------------------------------------------------------------- /static/images/site/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/home.png -------------------------------------------------------------------------------- /static/images/site/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/link.png -------------------------------------------------------------------------------- /static/images/site/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/mail.png -------------------------------------------------------------------------------- /static/images/site/print.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/print.png -------------------------------------------------------------------------------- /static/images/site/reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/reply.png -------------------------------------------------------------------------------- /templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends articles %} 2 | 3 | {% block articles_content %} 4 | {{ content }} 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /static/assets/04/unsigned.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/unsigned.jpg -------------------------------------------------------------------------------- /static/images/site/attach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/attach.png -------------------------------------------------------------------------------- /static/images/site/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/console.png -------------------------------------------------------------------------------- /static/images/site/create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/create.png -------------------------------------------------------------------------------- /static/images/site/events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/events.png -------------------------------------------------------------------------------- /static/images/site/forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/forward.png -------------------------------------------------------------------------------- /static/images/site/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/github.png -------------------------------------------------------------------------------- /static/images/site/ideone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/ideone.png -------------------------------------------------------------------------------- /static/images/site/retweet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/retweet.png -------------------------------------------------------------------------------- /static/images/site/spritesheet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/spritesheet -------------------------------------------------------------------------------- /static/images/site/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/twitter.png -------------------------------------------------------------------------------- /static/images/site/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/warning.png -------------------------------------------------------------------------------- /static/images/site/youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/youtube.png -------------------------------------------------------------------------------- /static/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/android-chrome-192x192.png -------------------------------------------------------------------------------- /static/android-chrome-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/android-chrome-256x256.png -------------------------------------------------------------------------------- /static/android-chrome-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/android-chrome-384x384.png -------------------------------------------------------------------------------- /static/assets/03/flat_2d@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/03/flat_2d@1x.png -------------------------------------------------------------------------------- /static/assets/04/categories.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/categories.jpg -------------------------------------------------------------------------------- /static/assets/04/chart-types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/chart-types.png -------------------------------------------------------------------------------- /static/assets/04/pie-chart.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/pie-chart.jpeg -------------------------------------------------------------------------------- /static/assets/04/unsigned-2d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/unsigned-2d.jpg -------------------------------------------------------------------------------- /static/images/site/backwards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/backwards.png -------------------------------------------------------------------------------- /static/images/site/clipboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/clipboard.png -------------------------------------------------------------------------------- /static/images/site/comments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/comments.png -------------------------------------------------------------------------------- /static/images/site/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/download.png -------------------------------------------------------------------------------- /static/images/site/feedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/feedback.png -------------------------------------------------------------------------------- /static/images/site/ideone.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/ideone.sketch -------------------------------------------------------------------------------- /static/images/site/more-tags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/more-tags.png -------------------------------------------------------------------------------- /templates/includes/sidebar/google-translate.html: -------------------------------------------------------------------------------- 1 |
2 | {%- include includes/extensions/google-translate.html -%} 3 |
4 | -------------------------------------------------------------------------------- /static/assets/general/EnVivo@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/general/EnVivo@1x.png -------------------------------------------------------------------------------- /static/assets/general/GitHub@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/general/GitHub@1x.png -------------------------------------------------------------------------------- /static/assets/general/Sharp@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/general/Sharp@1x.png -------------------------------------------------------------------------------- /static/assets/general/Twitch@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/general/Twitch@1x.png -------------------------------------------------------------------------------- /static/images/site/favicon@260w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/favicon@260w.png -------------------------------------------------------------------------------- /static/images/site/footer-dots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/footer-dots.png -------------------------------------------------------------------------------- /static/images/site/spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/spritesheet.png -------------------------------------------------------------------------------- /static/images/site/warning-big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/warning-big.png -------------------------------------------------------------------------------- /static/images/site/youtube-big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/youtube-big.png -------------------------------------------------------------------------------- /static/assets/04/landscape-colors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/landscape-colors.png -------------------------------------------------------------------------------- /static/assets/04/technology-stocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/technology-stocks.png -------------------------------------------------------------------------------- /static/assets/04/top2500feelings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/top2500feelings.png -------------------------------------------------------------------------------- /static/assets/general/Discord@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/general/Discord@1x.png -------------------------------------------------------------------------------- /static/assets/general/Twitter@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/general/Twitter@1x.png -------------------------------------------------------------------------------- /static/assets/general/YouTube@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/general/YouTube@1x.png -------------------------------------------------------------------------------- /static/images/site/header-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/header-detail.png -------------------------------------------------------------------------------- /static/assets/03/2d_with_strides@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/03/2d_with_strides@1x.png -------------------------------------------------------------------------------- /static/assets/04/grammar-of-graphics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/grammar-of-graphics.png -------------------------------------------------------------------------------- /static/images/site/forward_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/forward_disabled.png -------------------------------------------------------------------------------- /static/images/site/line-number-body.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/line-number-body.png -------------------------------------------------------------------------------- /static/images/site/line-number-foot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/line-number-foot.png -------------------------------------------------------------------------------- /static/images/site/line-number-head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/line-number-head.png -------------------------------------------------------------------------------- /static/images/site/title-panel-dots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/title-panel-dots.png -------------------------------------------------------------------------------- /static/assets/02/vector-tensor-matriz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/02/vector-tensor-matriz.jpg -------------------------------------------------------------------------------- /static/assets/03/flat_with_strides@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/03/flat_with_strides@1x.png -------------------------------------------------------------------------------- /static/assets/04/Playfair_TimeSeries-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/Playfair_TimeSeries-2.png -------------------------------------------------------------------------------- /static/assets/04/sphx_glr_anatomy_001.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/04/sphx_glr_anatomy_001.webp -------------------------------------------------------------------------------- /static/images/site/backwards_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/images/site/backwards_disabled.png -------------------------------------------------------------------------------- /templates/about.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | hidden: 4 | - header 5 | - navigator 6 | - related_posts 7 | --- 8 | 9 | {{ content }} 10 | -------------------------------------------------------------------------------- /static/assets/02/filip-gielda-VPavA7BBxK0-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/02/filip-gielda-VPavA7BBxK0-unsplash.jpg -------------------------------------------------------------------------------- /static/assets/02/alfred-kenneally-UsgLeLorRuM-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/thatcsharpguy.com/main/static/assets/02/alfred-kenneally-UsgLeLorRuM-unsplash.jpg -------------------------------------------------------------------------------- /templates/includes/views/article.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | {{ content }} 6 | 7 |
8 | 9 |
10 | -------------------------------------------------------------------------------- /templates/includes/views/site-brand.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /static/discord/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

If you are not redirected in five seconds, click here.

8 | 9 | -------------------------------------------------------------------------------- /static/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #00aba9 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /content/posts/tv/2019-03-03-por-fin-de-vuelta.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ¡Por fin de vuelta! 3 | date: 2018-03-03 18:00:00 4 | youtube_id: 9j2m04mn9LU 5 | categories: meta 6 | summary: ¡Por fin de vuelta! 7 | lang: es 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | ¡Por fin de vuelta! 14 | -------------------------------------------------------------------------------- /templates/articles.html: -------------------------------------------------------------------------------- 1 | {% extends framework %} 2 | 3 | {% block framework_content %} 4 |
5 | {% if page.banner == nil %} 6 | {% assign banner = page.title %} 7 | {% endif %} 8 | 9 | {% block articles_content %} 10 | {% endblock %} 11 | 12 | {% include includes/views/pagination.html %} 13 |
14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /templates/includes/sidebar/tag-list.html: -------------------------------------------------------------------------------- 1 | {%- include includes/functions/log.html level='debug' msg='Get tags value' -%} 2 | 3 | {%- include includes/functions/get_tags.html -%} 4 | {% assign tags = return %} 5 | 6 | {% assign keys = tags %} 7 | {% assign field = 'tags' %} 8 | {% assign url = '/tags.html' | relative_url %} 9 | {%- include sidebar/common-list.html -%} 10 | -------------------------------------------------------------------------------- /templates/includes/functions/get_tags.html: -------------------------------------------------------------------------------- 1 | {% assign split_mark = '<|>' %} 2 | 3 | {% assign tags = '' %} 4 | {% for tag in site.tags %} 5 | {% assign name = tag | first %} 6 | {% assign tags = tags | append: split_mark | append: name %} 7 | {% endfor %} 8 | 9 | {% assign return = tags 10 | | remove_first: split_mark 11 | | split: split_mark 12 | | sort: self %} 13 | -------------------------------------------------------------------------------- /templates/includes/extensions/mathjax.html: -------------------------------------------------------------------------------- 1 | 9 | 11 | -------------------------------------------------------------------------------- /templates/includes/sidebar/category-list.html: -------------------------------------------------------------------------------- 1 | {%- include includes/functions/log.html level='debug' msg='Get categories value' -%} 2 | 3 | {%- include includes/functions/get_categories.html -%} 4 | {% assign categories = return %} 5 | 6 | {% assign keys = categories %} 7 | {% assign field = 'categories' %} 8 | {% assign url = '/categories.html' | relative_url %} 9 | {% include sidebar/common-list.html %} 10 | -------------------------------------------------------------------------------- /templates/includes/functions/get_categories.html: -------------------------------------------------------------------------------- 1 | {% assign split_mark = '<|>' %} 2 | 3 | {% assign categories = '' %} 4 | {% for category in site.categories %} 5 | {% assign name = category | first %} 6 | {% assign categories = categories | append: split_mark | append: name %} 7 | {% endfor %} 8 | 9 | {% assign return = categories 10 | | remove_first: split_mark 11 | | split: split_mark 12 | | sort: self %} 13 | -------------------------------------------------------------------------------- /templates/includes/sidebar/archive-list.html: -------------------------------------------------------------------------------- 1 | {%- include includes/functions/log.html level='debug' msg='Get datetimes value' -%} 2 | 3 | {% assign filter = '%Y' %} 4 | {% include includes/functions/get_datetimes.html %} 5 | {% assign datetimes = return %} 6 | 7 | {% assign keys = datetimes %} 8 | {% assign field = 'date' %} 9 | {% assign url = '/archives.html' | relative_url %} 10 | {% include sidebar/common-list.html %} 11 | -------------------------------------------------------------------------------- /templates/framework.html: -------------------------------------------------------------------------------- 1 | {% extends default %} 2 | 3 | {% block default_content %} 4 |
5 |
6 | {% block framework_content %} 7 | {% endblock %} 8 |
9 | 14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /templates/includes/views/post-item.html: -------------------------------------------------------------------------------- 1 | {%- if include.item -%} 2 | {%- assign item = include.item -%} 3 | {%- endif -%} 4 | 5 | {%- assign post = item -%} 6 | 7 | {% assign date_format = site.yat.date_format | default: "%b %-d, %Y" %} 8 | {{ post.date | date: date_format }} 9 | 10 | 11 | {{ post.title | escape }} 12 | 13 | 14 | -------------------------------------------------------------------------------- /content/posts/tv/2017-09-06-escuela.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: La escuela | #meta 3 | date: 2017-09-06 18:00:00 4 | youtube_id: aq5B6VanedI 5 | images_folder: /tv/meta/ 6 | summary: Vuelvo a la escuela y me tomeré 4 semanas para adaptarme nuevamente a la vida de estudiante (y encontrar un buen lugar para grabar). 7 | featured_image: escuela1.png 8 | tweet_id: 905451303282802688 9 | tags: Meta, YouTube 10 | featured_tag: Tv 11 | layout: video 12 | --- 13 | 14 | -------------------------------------------------------------------------------- /content/posts/tv/2018-08-21-2048-seguidores.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ¡2048 seguidores! 3 | date: 2018-08-21 18:00:00 4 | youtube_id: 4CHvhTRftnk 5 | categories: meta 6 | summary: "Tres cosas: Gracias, gracias y gracias. Dejen sus preguntas aquí o en mis redes sociales." 7 | lang: es 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | Tres cosas: Gracias, gracias y gracias. Dejen sus preguntas aquí o en mis redes sociales. 14 | -------------------------------------------------------------------------------- /templates/categories.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: framework 3 | sidebar: category-list 4 | --- 5 | 6 | {%- if site.posts.size > 0 -%} 7 | 8 | {%- include includes/functions/log.html level='debug' msg='Get value' -%} 9 | {%- include includes/functions/get_categories.html -%} 10 | {% assign categories = return %} 11 | 12 | {% assign keys = categories %} 13 | {% assign field = 'categories' %} 14 | {%- include includes/views/segments.html -%} 15 | 16 | {%- endif -%} 17 | -------------------------------------------------------------------------------- /templates/includes/functions/log.html: -------------------------------------------------------------------------------- 1 | {% if include.params.level %} 2 | {% assign level = include.params.level %} 3 | {% endif %} 4 | 5 | {% if include.params.msg %} 6 | {% assign msg = include.params.msg %} 7 | {% endif %} 8 | 9 | {% if site.debug == true %} 10 | {% if level == 'debug' %} 11 | {% if jekyll.environment == "development" %} 12 | 13 | {% endif %} 14 | {% else %} 15 | 16 | {% endif %} 17 | {% endif %} 18 | -------------------------------------------------------------------------------- /templates/includes/extensions/favicon.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /templates/archives.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: framework 3 | sidebar: archive-list 4 | --- 5 | 6 | {%- if site.posts.size > 0 -%} 7 | 8 | {% include includes/functions/log.html level='debug' msg='Get datetimes value' %} 9 | 10 | {% assign filter = '%Y' %} 11 | {% include includes/functions/get_datetimes.html %} 12 | {% assign datetimes = return %} 13 | 14 | {% assign keys = datetimes | reverse %} 15 | {% assign field = 'date' %} 16 | {% include includes/views/segments.html %} 17 | 18 | {%- endif -%} 19 | -------------------------------------------------------------------------------- /content/posts/tv/2019-03-11-machine-learning.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Machine Learning 3 | date: 2019-03-11 18:00:00 4 | youtube_id: KwjQQcx7sMA 5 | categories: data-science 6 | summary: El aprendizaje máquina es maravilloso, pero no es magia. Todo depende de la información que tengamos a la mano. 7 | lang: es 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | El aprendizaje máquina es maravilloso, pero no es magia. Todo depende de la información que tengamos a la mano. 14 | -------------------------------------------------------------------------------- /templates/404.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | 18 | 19 |
20 |

404

21 | 22 |

Page not found :(

23 |

Try to check other pages through the menu.

24 |
25 | -------------------------------------------------------------------------------- /templates/includes/functions/get_datetimes.html: -------------------------------------------------------------------------------- 1 | {% if include.params.filter %} 2 | {% assign filter = include.params.filter %} 3 | {% endif %} 4 | 5 | {% assign split_mark = '<|>' %} 6 | 7 | {% assign dates = '' %} 8 | {% for post in site.posts %} 9 | {% assign name = post.date | date: filter %} 10 | {% assign dates = dates | append: split_mark | append: name %} 11 | {% endfor %} 12 | 13 | {% assign return = dates 14 | | remove_first: split_mark 15 | | split: split_mark 16 | | sort: self 17 | | uniq %} 18 | 19 | -------------------------------------------------------------------------------- /static/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TCSG", 3 | "short_name": "TCSG", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-384x384.png", 12 | "sizes": "384x384", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /content/posts/tv/2017-03-14-pruebas-unitarias-vs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Pruebas unitarias en Visual Studio 3 | slug: pruebas-unitarias-vs 4 | date: 2017-03-14 19:00:00 5 | youtube_id: W-p8wia0HzA 6 | images_folder: /tv/unit-test/ 7 | summary: Aprende a crear pruebas unitarias usando C# 8 | featured_image: featured.jpg 9 | tags: AprendeCSharp, VisualStudio, YouTube 10 | featured_tag: AprendeCSharp 11 | layout: video 12 | --- 13 | 14 | ¿Aún no sabes qué son las pruebas unitarias? ve mi otro vídeo 15 | -------------------------------------------------------------------------------- /content/posts/tv/2019-04-15-overfitting-underfitting.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Overfitting, underfiting y regresión polinomial 3 | date: 2019-04-15 18:00:00 4 | youtube_id: ONSxjoV9LjM 5 | categories: data-science 6 | summary: Entrenar mucho o poco... he ahí el dilema. Conoce sobre el sub ajuste, el sobre ajuste y cómo podemos combatirlo. 7 | lang: es 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | Notebook para las animaciones: https://colab.research.google.com/drive/13CGxYYnHzNcBSWOnfMZn2Bkfm68FpQBc 14 | -------------------------------------------------------------------------------- /content/posts/tv/2019-05-27-svm-explanation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Machine learning: Clasificación y las support vector machines" 3 | date: 2019-05-27 18:00:00 4 | youtube_id: pLLlX0juXGo 5 | tweet_id: 1133103424772431872 6 | categories: data-science 7 | summary: Clasificación usando support vector machines 8 | lang: es 9 | tags: Data science, Meta, YouTube 10 | featured_tag: Tv 11 | layout: video 12 | --- 13 | 14 | Lecture on SVM: https://www.youtube.com/watch?v=eHsErlPJWUU 15 | SVM animations: https://github.com/fferegrino/mlconcepts/blob/master/notebooks/svm/SVM%20graphics.ipynb -------------------------------------------------------------------------------- /content/posts/tv/2019-04-01-regresion-lineal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: La regresión lineal 3 | date: 2019-04-01 18:00:00 4 | youtube_id: Ug4KwWVMEIc 5 | categories: development, python 6 | summary: La regresión lineal es uno de los algoritmos más básicos de machine learning, es el punto de entrada a muchos otros algoritmos de este campo. 7 | lang: es 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | La regresión lineal es uno de los algoritmos más básicos de machine learning, es el punto de entrada a muchos otros algoritmos de este campo. 14 | -------------------------------------------------------------------------------- /content/posts/tv/2017-06-27-implementacion-mvc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Una implementación de MVC 3 | slug: implementacion-mvc 4 | date: 2017-06-27 18:00:00 5 | youtube_id: ym4E-6EF3SA 6 | images_folder: /tv/mvc/ 7 | summary: Así es como aplico el patrón MVC en algunos de los proyectos que desarrollo. 8 | featured_image: implementacion.jpg 9 | tags: Meta, YouTube 10 | featured_tag: Tv 11 | layout: video 12 | post-routes: 13 | - /post/{}/index.html 14 | - /tv/{}/index.html 15 | - /post/{}.html 16 | --- 17 | 18 | Obtén el código que describí en el video: enlace. -------------------------------------------------------------------------------- /content/posts/tv/2019-03-18-entornos-virtuales.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Entornos virtuales 3 | date: 2019-03-18 18:00:00 4 | youtube_id: GM-RcOaGN4w 5 | categories: development, python 6 | summary: Los entornos virtuales de Python nos ayudan a mantener una clara separación entre las dependencias de un proyecto y otro. Deberías tratar de usarlos siempre que puedas. 7 | lang: es 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | Los entornos virtuales de Python nos ayudan a mantener una clara separación entre las dependencias de un proyecto y otro. Deberías tratar de usarlos siempre que puedas. 14 | -------------------------------------------------------------------------------- /content/posts/tv/2019-04-10-numpy-pandas-parte-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: NumPy y Pandas (parte 1) 3 | date: 2019-04-10 18:00:00 4 | youtube_id: VsaiJtZy-Kg 5 | categories: development, python 6 | summary: Primera parte de este mini tutorial sobre NumPy y Pandas 7 | lang: es 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | Notebook: http://bit.ly/numpy-pandas 14 | Parte 2: https://youtu.be/jGrQtpWH09s 15 | 16 | From Python to NumPy: http://www.labri.fr/perso/nrougier/from-python-to-numpy/ 17 | 18 | Tentative NumPy Tutorial: http://scipy.github.io/old-wiki/pages/Tentative_NumPy_Tutorial 19 | -------------------------------------------------------------------------------- /content/posts/tv/2019-04-10-numpy-pandas-parte-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: NumPy y Pandas (parte 2) 3 | date: 2019-04-10 18:00:00 4 | youtube_id: jGrQtpWH09s 5 | categories: development, python 6 | summary: Segunda parte de este mini tutorial sobre NumPy y Pandas 7 | lang: es 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | Notebook: http://bit.ly/numpy-pandas 14 | Parte 1: https://youtu.be/VsaiJtZy-Kg 15 | 16 | 10 minutes to pandas: https://pandas.pydata.org/pandas-docs/stable/getting_started/10min.html 17 | 18 | Intro to pandas: https://uoftcoders.github.io/studyGroup/lessons/python/pandas/lesson/ 19 | -------------------------------------------------------------------------------- /content/posts/tv/2018-08-14-neo4j.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Neo4j 3 | date: 2018-08-14 18:00:00 4 | youtube_id: k3h_y9w_7l4 5 | categories: data-science 6 | summary: Neo4j es una base de datos orientada a almacenar información altamente relacionada. Su modelo de datos (el grafo etiquetado y con propiedades) otorgra una gran flexibilidad y rapidez al trabajar con grafos. 7 | lang: es 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | Neo4j es una base de datos orientada a almacenar información altamente relacionada. Su modelo de datos (el grafo etiquetado y con propiedades) otorgra una gran flexibilidad y rapidez al trabajar con grafos. -------------------------------------------------------------------------------- /templates/includes/views/segments.html: -------------------------------------------------------------------------------- 1 | {%- if include.keys -%} 2 | {%- assign keys = include.keys -%} 3 | {%- endif -%} 4 | 5 | {%- if include.field -%} 6 | {%- assign field = include.field -%} 7 | {%- endif -%} 8 | 9 |
10 | 21 |
22 | -------------------------------------------------------------------------------- /templates/includes/sidebar/common-list.html: -------------------------------------------------------------------------------- 1 | {%- if include.keys -%} 2 | {%- assign keys = include.keys -%} 3 | {%- endif -%} 4 | 5 | {%- if include.field -%} 6 | {%- assign field = include.field -%} 7 | {%- endif -%} 8 | 9 |
10 | 25 |
26 | -------------------------------------------------------------------------------- /templates/includes/views/paginator.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | {% if paginator.has_previous_page %} 4 | Página {{ paginator.previous_page }} 5 | {% else %} 6 | Nada por aquí 😎 7 | {% endif %} 8 | 9 | {{ paginator.page }}/{{ paginator.total_pages }} 10 | 11 | {% if paginator.has_next_page %} 12 | Página {{ paginator.next_page }} 13 | {% else %} 14 | 😎 Nada por acá 15 | {% endif %} 16 | 17 |
-------------------------------------------------------------------------------- /templates/includes/extensions/geopattern.html: -------------------------------------------------------------------------------- 1 | {% if include.selector %} 2 | {% assign selector = include.selector %} 3 | {% endif %} 4 | 5 | {% if include.seed %} 6 | {% assign seed = include.seed %} 7 | {% endif %} 8 | 9 | 10 | 21 | 22 | -------------------------------------------------------------------------------- /templates/tags.html: -------------------------------------------------------------------------------- 1 | {% extends framework %} 2 | 3 | {% block framework_content %} 4 |

THing

5 |
6 | 21 |
22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /templates/includes/extensions/comments/gitment.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 16 | -------------------------------------------------------------------------------- /content/posts/tv/2019-04-29-train-test-validate-split.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Machine Learning: train / validate / test " 3 | date: 2019-04-29 18:00:00 4 | youtube_id: 778Pa63FS78 5 | categories: data-science 6 | summary: "Descubre el por qué de la separación de nuestros datos en tres: los conjuntos de entrenamiento, validación y prueba, así como su relación con el algoritmo con el que estemos trabajando." 7 | lang: es 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | Descubre el por qué de la separación de nuestros datos en tres: los conjuntos de entrenamiento, validación y prueba, así como su relación con el algoritmo con el que estemos trabajando. 14 | -------------------------------------------------------------------------------- /templates/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include includes/head.html %} 5 | 6 | 7 | 8 | {%- include includes/views/header.html -%} 9 | 10 | {%- include includes/views/banner.html -%} 11 | 12 | {%- include includes/extensions/hashlocate.html -%} 13 | 14 | {%- include includes/extensions/theme-toggle.html -%} 15 | 16 |
17 |
18 | {% block default_content %} 19 | {% endblock %} 20 |
21 |
22 | 23 | {%- include includes/views/footer.html -%} 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /templates/includes/functions/get_article_words.html: -------------------------------------------------------------------------------- 1 | {% if include.params.article %} 2 | {% assign article = include.params.article %} 3 | {% endif %} 4 | 5 | {% if include.params.lang %} 6 | {% assign lang = include.params.lang %} 7 | {% else %} 8 | {% assign lang = lang | default: site.lang | default: "en" %} 9 | {% endif %} 10 | 11 | {% assign words = article | number_of_words %} 12 | 13 | {% if lang != "en" %} 14 | {% assign words = words 15 | | times: 0.6 16 | | round %} 17 | {% assign words = article 18 | | strip_html 19 | | strip_newlines 20 | | size 21 | | times: 0.4 22 | | plus: words 23 | | round %} 24 | {% endif %} 25 | 26 | {% assign return = words %} 27 | -------------------------------------------------------------------------------- /templates/includes/extensions/comments/disqus.html: -------------------------------------------------------------------------------- 1 |
2 | 17 | 18 | -------------------------------------------------------------------------------- /templates/includes/views/footer.html: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /site.yml: -------------------------------------------------------------------------------- 1 | title: "That C# guy" 2 | subtitle: Ingeniería de software + Ciencia de datos + MLOps 3 | description: Un sitio en donde se habla a veces de programación, a veces de ciencia de datos y muchas veces de MLOps. 4 | default-author: Antonio Feregrino 5 | site-url: https://thatcsharpguy.com 6 | social: 7 | - text: GitHub 8 | url: https://github.com/fferegrino 9 | - text: Twitter 10 | url: https://twitter.com/io_exception 11 | - text: YouTube 12 | url: https://youtube.com/thatcsharpguy 13 | - text: Discord 14 | url: https://tcsg.dev/discord 15 | routes: 16 | post-routes: 17 | - /post/{}/index.html 18 | - /post/{}.html 19 | tag-page-route: tag/{}/index.html 20 | tag-index-route: tag/index.html 21 | templates: 22 | post: post.html 23 | tag-page: post.html 24 | tag-index: tags.html 25 | index: home.html 26 | 27 | 28 | -------------------------------------------------------------------------------- /templates/includes/functions.html: -------------------------------------------------------------------------------- 1 | {%- assign params = include -%} 2 | {%- if params.func -%} 3 | {%- assign func = params.func -%} 4 | {%- endif -%} 5 | 6 | {%- assign include_path = func -%} 7 | {%- assign path_array = include_path | split: '.' -%} 8 | {%- if path_array.size == 1 -%} 9 | {%- assign include_path = include_path | append: '.html' -%} 10 | {%- endif -%} 11 | 12 | {%- if func == 'log' -%} 13 | {%- include functions/log.html level=include.level msg=include.msg -%} 14 | {%- else -%} 15 | {%- assign include_path = 'functions/' | append: include_path -%} 16 | {%- include {{ include_path }} params=params-%} 17 | {%- endif -%} 18 | 19 | {%- if func != 'log' -%} 20 | {%- assign msg = '[function][' 21 | | append: {{func}} 22 | | append: '] ' 23 | | append: {{return}} 24 | -%} 25 | {%- include includes/functions/log.html level='info' -%} 26 | {%- endif -%} 27 | -------------------------------------------------------------------------------- /templates/includes/extensions/trianglify.html: -------------------------------------------------------------------------------- 1 | {% if include.selector %} 2 | {% assign selector = include.selector %} 3 | {% endif %} 4 | 5 | {% if include.seed %} 6 | {% assign seed = include.seed %} 7 | {% endif %} 8 | 9 | 10 | 27 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Main pipeline 2 | 3 | on: 4 | push: 5 | branches: main 6 | 7 | jobs: 8 | main: 9 | runs-on: ubuntu-latest 10 | steps: 11 | 12 | - name: Checkout main repository 13 | uses: actions/checkout@v2 14 | with: 15 | submodules: true 16 | 17 | - name: Setup .NET SDK 18 | uses: actions/setup-dotnet@v1 19 | with: 20 | dotnet-version: '5.0.x' # SDK Version to use; x will use the latest version of the 3.1 channel 21 | 22 | - name: Build website 23 | run: dotnet run --project ./lockdown/Lockdown/Lockdown.csproj -- build --root . --output _site 24 | 25 | - name: Deploy 🚀 26 | uses: JamesIves/github-pages-deploy-action@3.7.1 27 | with: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | BRANCH: docs 30 | FOLDER: _site 31 | CLEAN: true 32 | -------------------------------------------------------------------------------- /templates/includes/extensions/google-analytics.html: -------------------------------------------------------------------------------- 1 | 19 | 20 | -------------------------------------------------------------------------------- /content/posts/tv/2017-12-22-escuela-otra-vez.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: La escuela, otra vez 3 | date: 2017-12-22 18:00:00 4 | youtube_id: gF1zBsKFqU0 5 | images_folder: /tv/jupyter/ 6 | summary: Mi opinión sobre la escuela. 7 | featured_image: featured.png 8 | tweet_id: 944945874316218368 9 | tags: Meta, YouTube 10 | featured_tag: Tv 11 | layout: video 12 | --- 13 | 14 | - Mi opinión de la escuela, después de haber pasado más 15 años de estudiar voluntariamente, debe servir para tres cosas y las voy a decir en orden de importancia: 15 | - enseñar los temas de los que se trata es decir, que si el curso es de matemáticas, aprendas matemáticas. 16 | - enseñar a aprender el tema del que se trata, volviendo al ejemplo de las matemáticas, que aprendas a aprender matemáticas, que te enseñen como estudiar 17 | - Inspirar a aprender el tema, muy pocos cursos y profesores llegan a este nivel. Si un profesor (o su curso) te inspiran a aprender la materia de la que se trata, me parece que es el mayor logro -------------------------------------------------------------------------------- /templates/includes/views/post-header.html: -------------------------------------------------------------------------------- 1 |
2 |

{{ post.title | escape }}

3 | 4 | 5 |

6 | 9 | {% assign reading_time = 'Test reading time' %} 10 | {{ post.author | default: site.default_author }} 11 |

12 | 13 | {%- if post.tags.size > 0 -%} 14 |
15 | {%- for tag in post.tags -%} 16 | 17 | 18 | {%- endfor -%} 19 |
20 | {%- endif -%} 21 | 22 |
23 | -------------------------------------------------------------------------------- /content/posts/tv/2016-12-06-subiendo-github.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Subiéndo código a GitHub 3 | slug: subiendo-github 4 | date: 2016-12-06 18:00:00 5 | youtube_id: lNBFt733izY 6 | images_folder: /tv/ 7 | summary: Un tutorial de cómo empezar con GitHub desde cero. 8 | featured_image: github.jpg 9 | tweet_id: 806267841733345281 10 | tags: Git, GitHub, YouTube 11 | featured_tag: Tv 12 | layout: video 13 | --- 14 | 15 | En el video menciono de un post que me ayudó a entender las licencias, lo puedes consultar aquí: A Short Guide To Open-Source And Similar Licenses 16 | 17 | ## Sitios web 18 | -------------------------------------------------------------------------------- /content/pages/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: About 4 | alias: /about/ 5 | lang: en 6 | --- 7 | 8 | #### Antonio Feregrino 9 | Programmer, eager to teach but more to learn. Passionate about what I do, I wrote my first calculator in C# back in 2008 and I haven't stopped since then. It took me 6 years to finish the university while writing code at Heurística Soluciones. I used to be a Microsoft Student Partner and first generation member of the Xamarin Student Partners, I have got a nice trophy from Xamarin which says that I'm a certified mobile developer. 10 | 11 |
12 | **This is important: While I love C#, I have alwyas believed that the most important thing is to have great ideas and to know how to express them, the language isn't as important.** 13 | 14 | #### This blog 15 | This is a blog about computer science and programming. It is made using [Jekyll on a Windows 8.1 machine](http://jekyll-windows.juthilo.com) y and [Code](https://code.visualstudio.com) as main editor. For some reason all the code is on [GitHub](http://github.com/fferegrino/that-c-sharp-guy) if you want to check it out. -------------------------------------------------------------------------------- /content/posts/tv/2016-04-18-hola-mundo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ¡Hola mundo (en video)! 3 | slug: hello-world-yt 4 | date: 2016-04-18 18:00:00 5 | youtube_id: m8wDykJZnvM 6 | categories: c-sharp 7 | summary: Video de presentación de este nuevo canal de YouTube en donde, a pesar del nombre, no solamente hablaré de C#, si no de varias muchas otras cosas relacionadas con la programación. 8 | featured_image: featured.png 9 | lang: es 10 | images_folder: /tv/hola-mundo/ 11 | tags: Meta, YouTube 12 | featured_tag: Tv 13 | layout: video 14 | --- 15 | 16 | Este es el video de presentación de este nuevo canal de YouTube en donde, a pesar del nombre, no solamente hablaré de C#, si no de varias muchas otras cosas relacionadas con la programación. 17 | 18 | En este canal podrás encontrar: 19 | 20 | - Explicaciones de patrones de diseño, conceptos de programación y algoritmos 21 | - Reseñas de aplicaciones para desarrollar 22 | - Reseñas de librerías, estas si serán específicas para C# 23 | 24 | 25 | Y temas de este tipo, te invito a que te suscribas en el botón que está un poco más abajo. Y pues nos vemos en el siguiente video. -------------------------------------------------------------------------------- /content/posts/tv/2017-07-11-implementacion-orm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: El ORM Entity Framework 3 | slug: implementacion-orm 4 | date: 2017-07-11 18:00:00 5 | youtube_id: cIZB1wNMPlY 6 | images_folder: /tv/orm/ 7 | summary: Este es un ejemplo de ORM, el framework Entity Framework, inicialmante desarrollado por Microsoft. 8 | featured_image: overlay-code.png 9 | tags: Meta, YouTube 10 | featured_tag: Tv 11 | layout: video 12 | post-routes: 13 | - /post/{}/index.html 14 | - /tv/{}/index.html 15 | - /post/{}.html 16 | --- 17 | 18 | Obtén el código que describí en el video: enlace. 19 | 20 | Aquí pueden encontrar el resto de las anotaciones que pueden usar con Entity Framework. 21 | 22 | Visita http://www.entityframeworktutorial.net/ para aprender de Entity Framework. O http://www.tutorialspoint.com/entity_framework/ donde también podrás encontrar tutoriales. -------------------------------------------------------------------------------- /.liquidrc: -------------------------------------------------------------------------------- 1 | { 2 | "ignore": [ 3 | { 4 | "type": "liquid", 5 | "begin": "comment", 6 | "end": "endcomment" 7 | }, 8 | { 9 | "type": "html", 10 | "begin": "script", 11 | "end": "script" 12 | }, 13 | { 14 | "type": "html", 15 | "begin": "style", 16 | "end": "style" 17 | } 18 | ], 19 | "html": { 20 | "correct": false, 21 | "force_attribute": false, 22 | "braces": false, 23 | "preserve": 2, 24 | "unformatted": false 25 | }, 26 | "js": { 27 | "preserve": 1, 28 | "method_chain": 0, 29 | "quote_convert": "none", 30 | "format_array": "indent", 31 | "format_object": "indent", 32 | "braces": false, 33 | "no_semicolon": false, 34 | "brace_block": true 35 | }, 36 | "scss": { 37 | "css_insert_lines": true, 38 | "preserve": 2, 39 | "braces": false, 40 | "brace_block": true 41 | }, 42 | "css": { 43 | "css_insert_lines": true, 44 | "preserve": 2, 45 | "braces": false, 46 | "brace_block": true 47 | }, 48 | "json": { 49 | "preserve": 0, 50 | "braces": false, 51 | "brace_block": true, 52 | "no_semicolon": true 53 | } 54 | } -------------------------------------------------------------------------------- /templates/includes/functions/get_value.html: -------------------------------------------------------------------------------- 1 | {%- if include.params.name -%} 2 | {%- assign name = include.params.name -%} 3 | {%- endif -%} 4 | {%- assign keys = name | split:'.'- %} 5 | {%- assign name = keys.first -%} 6 | 7 | {%- if post.extras[name] != nil -%} 8 | {%- assign return = post.extras[name] -%} 9 | {%- elsif site[name] != nil -%} 10 | {%- assign return = site[name] -%} 11 | {%- elsif site.data[name] != nil -%} 12 | {%- assign return = site.data[name] -%} 13 | {%- elsif site.defaults[page.layout][name] != nil -%} 14 | {%- assign return = site.defaults[page.layout][name] -%} 15 | {%- elsif site.data.defaults[page.layout][name] != nil -%} 16 | {%- assign return = site.data.defaults[page.layout][name] -%} 17 | {%- elsif layout[name] != nil -%} 18 | {%- assign return = layout[name] -%} 19 | {%- else -%} 20 | {%- assign return = include.params.default -%} 21 | {%- endif -%} 22 | 23 | {% comment %} 24 | {%- assign keys = keys | shift -%} 25 | {%- for key in keys -%} 26 | {%- assign return = return[key] -%} 27 | {%- if return == nil -%} 28 | {%- assign return = include.params.default -%} 29 | {%- break -%} 30 | {%- endif -%} 31 | {%- endfor -%} 32 | {% endcomment %} -------------------------------------------------------------------------------- /templates/includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {%- include includes/extensions/favicon.html -%} 7 | {%- include includes/extensions/seo.html -%} 8 | 9 | 10 | 11 | 12 | 13 | 14 | {%- if jekyll.environment == 'production' and site.google_analytics -%} 15 | {%- include includes/extensions/google-analytics.html -%} 16 | {%- endif -%} 17 | {%- include includes/extensions/code-highlight.html -%} 18 | 19 | -------------------------------------------------------------------------------- /templates/includes/extensions/hashlocate.html: -------------------------------------------------------------------------------- 1 | 44 | -------------------------------------------------------------------------------- /templates/includes/views/banner.html: -------------------------------------------------------------------------------- 1 | {% assign banner_html = post-header.html %} 2 | 3 | {% assign name = 'banner' %} 4 | {%- include includes/functions/get_value.html -%} 5 | {% assign banner = return %} 6 | 7 | {% assign name = 'title' %} 8 | {%- include includes/functions/get_value.html -%} 9 | {% assign heading = return %} 10 | 11 | {% assign name = 'subtitle' %} 12 | {%- include includes/functions/get_value.html -%} 13 | {% assign subheading = return %} 14 | 15 | {% if banner %} 16 |
17 |
18 |
19 |
20 |
21 |
22 | 23 | {%- if banner_html -%} 24 | 25 | {%- assign banner_html = 'includes/views/' | append: banner_html -%} 26 | {%- include {{ banner_html }} -%} 27 | 28 | {%- else -%} 29 | 30 |
31 |

32 | {{ heading | default: page.title | escape }} 33 |

34 |

35 | {{ subheading | default: page.subtitle | escape }} 36 |

37 |
38 | 39 | {%- endif -%} 40 |
41 |
42 |
43 | {%- endif -%} 44 | 45 | -------------------------------------------------------------------------------- /static/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /templates/includes/views/pagination.html: -------------------------------------------------------------------------------- 1 | {%- if page.paginator -%} 2 | {%- assign paginator = page.paginator -%} 3 | {%- elsif paginator == nil -%} 4 | {%- assign paginator = site -%} 5 | {%- endif -%} 6 | 7 | {%- if paginator.posts.size > 0 -%} 8 | 39 | {%- endif -%} 40 | -------------------------------------------------------------------------------- /content/posts/tv/2016-07-13-sal-sintactica.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sal sintáctica 3 | slug: sal-sintactica 4 | date: 2016-07-13 18:00:00 5 | youtube_id: Klt-JnVaHIc 6 | images_folder: /tv/sal-sintactica/ 7 | categories: c-sharp 8 | summary: La sal sintáctica, cuyo objetivo es supuestamente ser lo totalmente opuesto a la azúcar, hacen difícil escribir mal código y, en teoría, hacen más difícil de usar un lenguaje. 9 | featured_image: featured.jpg 10 | tags: Meta, YouTube 11 | featured_tag: Tv 12 | layout: video 13 | --- 14 | 15 | En un video anterior había hablado de la azúcar sintáctica (si no lo has visto, aquí está el enlace). 16 | 17 | A partir de la azúcar sintáctica también se acuñaron otros términos, como el de la "sacarina sintáctica" que es más o menos como la azúcar: parece que ayuda "endulzar" el código pero sin necesariamente facilitar su escritura o su lectura y algunas veces lo complica. 18 | 19 | Y luego también está la *sal sintáctica*, cuyo objetivo es supuestamente ser lo totalmente opuesto a la azúcar: hacen difícil escribir mal código y, en teoría, hacen más difícil de usar un lenguaje. 20 | 21 | Además, a diferencia de la azúcar sintáctica, la sal no es opcional y por el contrario, es necesaria para escribir un programa. 22 | 23 | Por ejemplo tenemos: 24 | 25 | - Los corchetes `{` `}` 26 | - El `;` 27 | - El tener que escribir alguna palabra reservada para marcar el fin de una expresión, como `END FOR` o `END IF` 28 | - Inclusive hay quien considera el tipado fuerte como sal sintáctica. 29 | 30 | Pareciera que lo esencial de un lenguaje resulta ser la llamada "sal", y es que si no son lo mismo, la diferencia es mínima. 31 | -------------------------------------------------------------------------------- /content/posts/2015-07-18-hello-world.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Hello World 4 | date: 2015-07-18 18:31:38 5 | author: Antonio Feregrino 6 | categories: blog 7 | summary: I've decided to kill my old blog, if you ever visit [blog.fferegrino.org] again you'll find that it isn't what it used to be. I decided to divide the content and if you came here looking for technical stuff, this is the right place. 8 | alias: /hello-world/index.html 9 | tags: Meta 10 | featured_tag: Meta 11 | --- 12 | 13 | I've decided to kill my old blog, if you ever visit [blog.fferegrino.org] again you'll find that it isn't what it used to be. I decided to divide the content and if you came here looking for technical stuff, this is the right place. 14 | 15 | #### ¿Why changing? 16 | I wasn't really comfortable with the appearance of the old one, it started in blogger in september 2010 with my poor html knowledge by then, not mentioning the limitations that blogger had at that point. It barely got through bout carrying a lot of issues: hardcoded stuff, some css "hacks" that became obsolete as time passed and some other atrocities that I wouldn't commit again. Then I tried to migrate it to WordPress but while the new posts looked great, the old ones looked terribly awful, that fact even demotivated me to write new stuff. 17 | 18 | 19 | #### C#, wouldn't you write about anything else? 20 | That is just the name of the blog, as many people recognises mi for knowing a lot of C#, but it doesn't mean that I'm obsessed with just that technology and the fact that this blog is made using Jekyll is a proof to that. Here you’ll find about everything, after all that’s the developer life. 21 | 22 | [blog.fferegrino.org]: http://blog.fferegrino.org 23 | -------------------------------------------------------------------------------- /content/posts/tv/2017-08-15-mis-libros.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Mis libros (meta) 3 | date: 2017-08-15 18:00:00 4 | youtube_id: 6KhxYN8SQjw 5 | images_folder: /tv/meta/ 6 | summary: El canal llegó a 5̶0̶0̶ 534 suscriptores y decidí hacer este video en el que no hablo de nada sobre el desarrollo. La programación habitual regresa la siguiente semana. 7 | featured_image: libros.png 8 | tags: Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | ¡Hey! el canal llegó a 5̶0̶0̶ 534 suscriptores y decidí hacer este video en el que no hablo de nada sobre el desarrollo. La programación habitual regresa la siguiente semana. 14 | 15 | ¿Te interesa conseguir los libros? dejo algunos enlaces de afiliado acá abajo: 16 | 17 | 1:18 C# in a Nutshell (5 http://amzn.to/2vwSHqx) (6 http://amzn.to/2hY3PYP) 18 | 1:55 Cracking the Coding Interview http://amzn.to/2vU3oEG 19 | 2:36 A Tour of C++ http://amzn.to/2wX4D2K 20 | 3:01 Soft Skills http://amzn.to/2wXeQwb 21 | 3:42 Compiladores http://bit.ly/2wXfKc7 22 | 4:02 Ingeniería de Software: http://bit.ly/2w67oSm 23 | 4:28 Clean Code http://amzn.to/2fEO3kF 24 | 4:52 Thinking LINQ http://amzn.to/2fEIClV 25 | 5:15 Level Up! http://amzn.to/2vUPfqC 26 | 5:43 Estructuras de Datos http://bit.ly/2wX6KUe 27 | 6:07 ASP.NET Web API 2 http://amzn.to/2vUCZGP 28 | 6:07 ASP.NET Web API 2 Recipes http://amzn.to/2hYkwDp 29 | 6:39 The Algorithm Design Manual http://amzn.to/2uCAtFo 30 | 6:59 Matemáticas para la computación http://bit.ly/2vUTT8c 31 | 7:38 Designing Web Usability http://bit.ly/2vwH96A 32 | 8:23 Teoria De Automatas Lenguajes Y Computacion http://bit.ly/2uGFJUc 33 | 8:50 Machine Learning Projects for .NET developers http://amzn.to/2uBSmEa 34 | 9:33 Resto de los libros https://youtu.be/jXvOifaUr1o?t=9m33s -------------------------------------------------------------------------------- /content/pages/acerca-de.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Acerca de 4 | alias: /acerca-de/ 5 | lang: es 6 | --- 7 | 8 | ## Antonio Feregrino 9 | Programador, con ganas de enseñar y muchas más de aprender. Apasionado de lo que hago, hice mi primera calculadora con C# en 2008 y no he parado desde entonces, terminé la universidad en 6 años mientras trabajaba escribiendo código en Heurística Soluciones. También fui Microsoft Student Partner y miembro de la primera generación de Xamarin Student Partners, tengo un bonito trofeo de Xamarin que dice que soy un desarrollador certificado. 10 | 11 | **Esto es importante: Me gusta C# pero siempre he creído que lo importante es tener buenas ideas y saber expresarlas, el lenguaje es lo de menos.** 12 | 13 | 14 | ## Sobre el blog 15 | That ~~C#~~ CS guy es un blog destinado a la enseñanza del lenguaje de programación C, al desarrollo de aplicaciones aplicando lo aprendido y a las ciencas computacionales. Podrás encontrar también recomendaciones de libros, sitios web, herramientas y cursos para mejorar tus habilidades. Ocasionalmente también encontraras videos sobre ingeniería de software y ciencia computacional. 16 | 17 | #### Citando 18 | Si quieres citar alguno de mis posts, puedes hacerlo, lo que pido es que agregues una referencia hacia este sitio (preferentemente a la parte que estás citando). 19 | 20 | #### Links de afiliado 21 | En ciertas ocasiones, es posible que un post contenga links de afiliado, estos son enlaces especiales a productos que cuando accedes a la tienda en línea a través de ellos y compras algo, yo recibo una comisión. Sin embargo todos los links de este tipo son a productos que he probado y confío o que estoy pensando en probar; habiendo dicho esto, ten por seguro que los hago con el único motivo de darte aún más valor al recomendarte un producto que te puede ser de utilidad y a la vez conseguir financiación para mantener el blog. -------------------------------------------------------------------------------- /static/js/main.js: -------------------------------------------------------------------------------- 1 | // Fix DOM matches function 2 | if (!Element.prototype.matches) { 3 | Element.prototype.matches = 4 | Element.prototype.matchesSelector || 5 | Element.prototype.mozMatchesSelector || 6 | Element.prototype.msMatchesSelector || 7 | Element.prototype.oMatchesSelector || 8 | Element.prototype.webkitMatchesSelector || 9 | function(s) { 10 | var matches = (this.document || this.ownerDocument).querySelectorAll(s), 11 | i = matches.length; 12 | while (--i >= 0 && matches.item(i) !== this) {} 13 | return i > -1; 14 | }; 15 | } 16 | 17 | // Get Scroll position 18 | function getScrollPos() { 19 | var supportPageOffset = window.pageXOffset !== undefined; 20 | var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat"); 21 | 22 | var x = supportPageOffset ? window.pageXOffset : isCSS1Compat ? document.documentElement.scrollLeft : document.body.scrollLeft; 23 | var y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop; 24 | 25 | return { x: x, y: y }; 26 | } 27 | 28 | var _scrollTimer = []; 29 | 30 | // Smooth scroll 31 | function smoothScrollTo(y, time) { 32 | time = time == undefined ? 500 : time; 33 | 34 | var scrollPos = getScrollPos(); 35 | var count = 60; 36 | var length = (y - scrollPos.y); 37 | 38 | function easeInOut(k) { 39 | return .5 * (Math.sin((k - .5) * Math.PI) + 1); 40 | } 41 | 42 | for (var i = _scrollTimer.length - 1; i >= 0; i--) { 43 | clearTimeout(_scrollTimer[i]); 44 | } 45 | 46 | for (var i = 0; i <= count; i++) { 47 | (function() { 48 | var cur = i; 49 | _scrollTimer[cur] = setTimeout(function() { 50 | window.scrollTo( 51 | scrollPos.x, 52 | scrollPos.y + length * easeInOut(cur/count) 53 | ); 54 | }, (time / count) * cur); 55 | })(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /content/posts/2015-11-02-xamarin-forms-mvvm-21-nov-2015.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Xamarin.Forms y MVVM en la ESCOM (21 de noviembre de 2015) 4 | date: 2015-11-02 22:00:00 5 | author: Antonio Feregrino 6 | categories: netduino c# 7 | summary: En el evento haremos juntos una app utilizando estas tecnologías mientras platicamos un poco acerca de MVVM y cómo implementarlo junto con Xamarin.Forms. 8 | lang: es 9 | featured_image: event.png 10 | images_folder: commons/ 11 | tags: Xamarin, Events 12 | featured_tag: Xamarin 13 | --- 14 | 15 | Siguiendo con el plan de llevar a cabo un evento mensual sobre Xamarin / C#, el siguiente sábado 21 de noviembre estaré en la Escuela Superior de Cómputo para hablar sobre Xamarin.Forms y MVVM. 16 |
17 | 18 | En el evento haremos juntos una app utilizando estas tecnologías mientras platicamos un poco acerca de: 19 | 31 |
32 | 33 | Si estás interesado en asistir, llena el formulario de pre-registro y yo me pondré en contacto contigo en cuanto el cupo se llene. 34 |
35 | 36 | En breve estaré subiendo el código y las diapositivas de la sesión para que ese día no haya contratiempos, pero por lo mientras puedes ir viendo qué necesitas para empezar con Xamarin o ver un ejemplo de qué es lo que se puede hacer con Xamarin.Forms. 37 | 38 |

Actualización

39 | ¡Xamarin es gratis para estudiantes a través de DreamSpark! accede a él a través de [este link](https://www.dreamspark.com/Product/Product.aspx?productid=100). -------------------------------------------------------------------------------- /content/posts/2015-07-11-hola-mundo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: ¡Hola mundo! 4 | date: 2015-07-11 18:31:38 5 | author: Antonio Feregrino 6 | categories: blog es 7 | summary: He decididio "matar" el blog anterior, si por casualidad llegan a blog.fferegrino.org, encontrarán que ya no es lo que era antes. He decidido dividir el contenido y si llegaron acá buscando cosas técnicas este es el lugar indicado. 8 | lang: es 9 | alias: /hola-mundo/index.html 10 | tags: Meta 11 | featured_tag: Meta 12 | --- 13 | 14 | He decididio "matar" el blog anterior, si por casualidad llegan a [blog.fferegrino.org], encontrarán que ya no es lo que era antes. He decidido dividir el contenido y si llegaron acá buscando cosas técnicas este es el lugar indicado. 15 | 16 | #### ¿Por qué cambiar de blog? 17 | En realidad ya no estaba muy a gusto con la vista que tenía el anterior, comenzó en blogger por allá de septiembre de 2010 con mis pocos conocimientos de html y con las limitaciones que presentaba blogger en ese momento. A marchas forzadas fue saliendo, pero también arrastrando muchos problemas, código duro, "hacks" de css que con el tiempo se volvieron obsoletos y demás atrocidades que sinceramente hoy no volvería a cometer. Intenté moverlo a WordPress, pero mientras que las cosas nuevas se veían mediánamente bien las antiguas se veían horrendo, hasta me desmotiviaba a escribir nuevas cosas. 18 | 19 | #### ¿Qué va a pasar con la información anterior? 20 | Trataré de mantener todo el antiguo blog a flote tanto como pueda, pero rescataré algunas de las entradas más populares y las republicaré de alguna manera aquí o en mi blog personal, segun sea el caso. 21 | 22 | #### ¿C#, ya no escribirás sobre nada más? 23 | Es solo el nombre del blog, y es que muchos me conocen por saber más de C#, pero no significa que esté obsesionado con una sola tecnología y el hecho de que este blog esté hecho en Jekyll es prueba de ello. Acá habrá de todo, así suele ser la vida de un desarrollador (y más si trabajas en una empresea pequeña). 24 | 25 | [blog.fferegrino.org]: http://blog.fferegrino.org 26 | -------------------------------------------------------------------------------- /content/posts/2016-06-02-mobile-c-sharp-workshop-17-oct-2016.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Diapositivas primer Meetup Xamarin Students México 4 | date: 2016-06-02 22:00:00 5 | author: Antonio Feregrino 6 | summary: Este es un post de recapitulación del evento Meetup Xamarin Students México del 1 de junio de 2016 en Urban Station 7 | lang: es 8 | featured_image: event.png 9 | images_folder: commons/ 10 | tags: Xamarin, XamarinForms, Events 11 | featured_tag: Xamarin 12 | --- 13 | 14 |
15 | 16 |
17 | 18 | Puedes checar el [código fuente en GitHub](https://github.com/fferegrino/custom-renderers-talk/releases/tag/m-1). 19 | 20 | ## Diapositiva 9 - Renderers de Xamarin.Forms 21 | [https://github.com/xamarin/Xamarin.Forms](https://github.com/xamarin/Xamarin.Forms) 22 | 23 | Button y sus implementaciones 24 | https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Core/Button.cs 25 | https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.iOS/Renderers/ButtonRenderer.cs 26 | https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.Android/Renderers/ButtonRenderer.cs 27 | https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.WinRT/ButtonRenderer.cs 28 | 29 | ## Diapositiva 10 - Aplicación demo 30 | 31 | EL cliente de la Pokéapi es Jirapi, hecho por mi http://thatcsharpguy.com/post/jirapi/ 32 | 33 | ## Diapositiva 12 - Effects 34 | 35 | https://developer.xamarin.com/guides/xamarin-forms/effects/introduction/ 36 | 37 | ## Diapositiva 15 - Ejemplos "reales" 38 | 39 | Xlabs: https://github.com/XLabs/Xamarin-Forms-Labs 40 | Telerik UI for Xamarin: http://www.telerik.com/xamarin-ui 41 | Messier16 Controls: https://github.com/messier16/Forms.Controls -------------------------------------------------------------------------------- /content/posts/tv/2016-07-20-first-class-citizens.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ciudadanos de primera clase 3 | slug: first-class-citizens 4 | date: 2016-07-20 18:00:00 5 | youtube_id: OoWKSgrnTwc 6 | images_folder: /tv/first-class-citizens/ 7 | categories: c-sharp 8 | summary: En programación, cuando se habla de ciudadanos de primera clase es para hacer referencia a un elemento del lenguaje que posee la mayor cantidad de privilegios. 9 | featured_image: fcc.jpg 10 | tweet_id: 755936816021270532 11 | tags: Meta, YouTube 12 | featured_tag: Tv 13 | layout: video 14 | --- 15 | 16 | En programación, cuando se habla de ciudadanos de primera clase o *First-class citizens* (o *first-class constructs* o *first-class elements*), es para hacer referencia a un elemento del lenguaje que posee la mayor cantidad de privilegios dentro de dicho lenguaje. 17 | 18 | En 1967 Christopher Strachey hizo referencia a los terminos objeto de primera y segunda clase para referirse a la diferencia entre un número real y un procedimiento, en términos del uso que podía tener cada uno de ellos en ALGOL. 19 | 20 | 21 | 22 | Consulta el documento completo en este enlace. 23 | 24 | A pesar de lo anterior, este no es un término bien definido, ya que varía por muchos factores, y el principal de ellos es el lenguaje de programación del cual estemos hablando. Pero hay ciertas características que generalmente se toman en cuenta para decir si un elemento es de primera clase o no: 25 | 26 | - Puede ser guardado en variables 27 | - Pueden ser usados como argumentos 28 | - Pueden ser un valor de retorno 29 | - Tienen identidad propia 30 | 31 | Es importante señalar que si bien "existen" ciudadanos de primera clase, no existen de segunda o tercera. Una cosa es de primera o no lo es. 32 | 33 | Por poner un ejemplo de cosas que son y no son, podemos decir que los `Enums` de C# no son de primera clase, ya que básicamente es azúcar sintáctica para referirnos a un número entero. 34 | 35 | Por otro lado, desde C# 3.0 podemos crear funciones, mediante `Func` o `Action` y tratarlas como de primera clase. -------------------------------------------------------------------------------- /content/posts/tv/2018-01-19-sobre-youtube.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: YouTube 3 | date: 2018-01-19 18:00:00 4 | youtube_id: 6NE0WD1wVGw 5 | summary: Ahora quisiera pedirles un favor. 6 | tags: Meta, YouTube 7 | featured_tag: Tv 8 | layout: video 9 | --- 10 | 11 | Como algunos de ustedes sabrán si es que siguen a otros canales, recientemente YouTube cambió las políticas para pertenecer a su programa de asociados, este programa de asociados incluye entre otras cosas, la habilidad de poner anuncios en los videos y la habilidad de poner links hacia sitios externos como este que es mi blog. 12 | 13 | En fin, a pesar de que YouTube dice que la visibilidad de los videos en el sitio no se verá afectada por si perteneces o no a este programa, la verdad es que yo no confío mucho en eso y no quisiera dejar de pertenecer a este programa. Los requisitos nuevos son tener más de 1,000 suscriptores los cuales, requisito que ya está cumplido gracias a ustedes, y 4000 horas de visualizaciones en los 12 meses anteriores, y es aquí en donde este canal se queda corto. 14 | 15 | Es por eso que ahora quisiera pedirles un favor, a los nuevos suscriptores, les pido que se den una vuelta por los videos más viejos y los vean, sé que si encontraron útiles los videos más recientes, los anteriores también les van a servir. Y a todos los demás en general, les pido que si conocen a alguien a quién le podría interesar de lo que hablo aquí, le cuenten de este canal, en una de esas les resulta de interés y se suscriben. 16 | 17 | Por estas dos cosas que les estoy pidiendo, muchas gracias. 18 | 19 | Fue hace como dos años que decidí comenzar a subir videos a YouTube, la idea era tratar de explicar cosas que en su momento me costaron un poco de trabajo entender y tratar de explicarlas de un modo en el que a mi me hubiera gustado que me las explicaran. En ese entonces ya sabía de sobremanera que YouTube no es un negocio rentable por si solo para el 99% de la gente que sube sus videos, es por eso que desde el inicio, la motivación de estar aquí no fue el dinero, sino las ganas de compartir mis conocimientos y aprender de la gente que deja sus comentarios en cada uno de los videos que hago. Yo seguiré haciendo videos de lo que sé y de lo que ustedes me digan que les podría resultar de utilidad. En fin, gracias por ver este video, ya pronto subiré otro con algo que si sea de utilidad, pero hasta entonces, nos vemos la próxima. -------------------------------------------------------------------------------- /content/posts/tv/2017-11-27-memoizacion.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Memoización 3 | slug: memoization 4 | date: 2017-11-27 18:00:00 5 | youtube_id: D_V7-K-BPXo 6 | images_folder: /tv/memoization/ 7 | summary: La memoización es una técnica de optimización de algoritmos que permite acelerar la ejecución de una función. 8 | featured_image: featured.png 9 | tweet_id: 935202027583483904 10 | tags: Meta, YouTube 11 | featured_tag: Tv 12 | layout: video 13 | --- 14 | 15 | Sí, memoización, no, no memorización. 16 | 17 | La memorización es una técnica de optimización usada en la programación que consiste en almacenar los resultados de funciones previamente calculadas para evitar ejecutarlas de nuevo cuando las necesitemos, en otras palabras, es básicamente "cachear" los resultados. 18 | 19 | Toma por ejemplo el cálculo de la sucesión de fibonacci, que como vimos, en un video anterior. Esto definido así: 20 | 21 | ``` 22 | Fib(0) = Fib(1) = 1 23 | Fib(n) = Fib(n-1) + Fib(n-2) 24 | ``` 25 | 26 | Como puedes ver, para el fibonacci de 5, llega un momento en el que empezamos a calcular valores que ya tenemos, y visto de esta manera estamos únicamente calculando 5 valores diferentes de las 13 operaciones que en "realidad" tendríamos que hacer. 27 | 28 | Así que, ¿que pasa si después de calcularlo la primera vez, lo almacenamos en una tabla o en un arreglo? Así, la siguiente vez que el valor sea requerido, podemos buscar si ya existe, y si sí, devolvemos el valor ya calculado. De otro modo vamos a tener que ejecutar la función y todas las que esta llame, nuevamente. 29 | 30 | Esto funciona bastante bien cuando el costo de ejecutar una función es muy alto, y se desperdiciarían recursos calculando valores que ya hemos calculado previamente. La memorización reduce el tiempo de ejecución a costa del espacio de almacenamiento, ya que, como vimos, para evitar calcular almacena los valores. Y es benéfica cuando de atacar problemas cuyas subsoluciones se deben resolver repetidamente, con la gran ventaja de solo calcular algunas cosas unas cuantas veces. 31 | 32 | Existen lenguajes que soportan y proveen una forma sencilla de implementar esta técnica, como a través de un decorador o una palabra clave... sin embargo existen otros en los que esta se tiene que implementar manualmente mediante el uso de alguna estructura de datos como un arreglo o un árbol binario. 33 | 34 | Además, la memorización juega un rol importante en la técnica de programación conocida como programación dinámica, de la cual muy pronto haré un video. -------------------------------------------------------------------------------- /templates/book.html: -------------------------------------------------------------------------------- 1 | {% extends framework %} 2 | 3 | {% block framework_content %} 4 |
5 |
6 | 7 | {%- assign banner = post.extras['banner'] -%} 8 | {%- assign banner_html = post-header.html -%} 9 | 10 | {%- if banner == nil -%} 11 | {%- include includes/views/post-header.html -%} 12 | {%- endif -%} 13 | 14 |
15 |
16 | {% block post_content %} 17 | {% endblock %} 18 |
19 |
20 | 21 | {%- assign result = hidden | where_exp: "item", "item == 'navigator'" -%} 22 | {%- if result.size == 0 -%} 23 |
24 | {%- if page.previous -%} 25 | 26 | {%- else -%} 27 | 28 | {%- endif -%} 29 | 30 | {%- if page.next -%} 31 | 32 | {%- else -%} 33 | 34 | {%- endif -%} 35 |
36 | {%- endif -%} 37 | 38 | {%- assign result = hidden | where_exp: "item", "item == 'related_posts'" -%} 39 | {%- if result.size == 0 -%} 40 |
41 |
Related Articles
42 | 48 |
49 | {%- endif -%} 50 | 51 | {%- assign result = hidden | where_exp: "item", "item == 'comments'" -%} 52 | {%- if result.size == 0 -%} 53 |
54 | {%- if page.comments != false -%} 55 | 56 | {%- if site.disqus.shortname -%} 57 | {%- include includes/extensions/comments/disqus.html -%} 58 | {%- endif -%} 59 | 60 | {%- if site.gitment.username -%} 61 | {%- include includes/extensions/comments/gitment.html -%} 62 | {%- endif -%} 63 | 64 | {%- endif -%} 65 |
66 | {%- endif -%} 67 | 68 |
69 |
70 | {% endblock %} -------------------------------------------------------------------------------- /templates/post.html: -------------------------------------------------------------------------------- 1 | {% extends framework %} 2 | 3 | {% block framework_content %} 4 |
5 |
6 | 7 | {%- assign banner = post.extras['banner'] -%} 8 | {%- assign banner_html = post-header.html -%} 9 | 10 | {%- if banner == nil -%} 11 | {%- include includes/views/post-header.html -%} 12 | {%- endif -%} 13 | 14 |
15 |
16 | {% block post_content %} 17 | {% endblock %} 18 |
19 |
20 | 21 | {%- assign result = hidden | where_exp: "item", "item == 'navigator'" -%} 22 | {%- if result.size == 0 -%} 23 |
24 | {%- if page.previous -%} 25 | 26 | {%- else -%} 27 | 28 | {%- endif -%} 29 | 30 | {%- if page.next -%} 31 | 32 | {%- else -%} 33 | 34 | {%- endif -%} 35 |
36 | {%- endif -%} 37 | 38 | {%- assign result = hidden | where_exp: "item", "item == 'related_posts'" -%} 39 | {%- if result.size == 0 -%} 40 |
41 |
Related Articles
42 | 48 |
49 | {%- endif -%} 50 | 51 | {%- assign result = hidden | where_exp: "item", "item == 'comments'" -%} 52 | {%- if result.size == 0 -%} 53 |
54 | {%- if page.comments != false -%} 55 | 56 | {%- if site.disqus.shortname -%} 57 | {%- include includes/extensions/comments/disqus.html -%} 58 | {%- endif -%} 59 | 60 | {%- if site.gitment.username -%} 61 | {%- include includes/extensions/comments/gitment.html -%} 62 | {%- endif -%} 63 | 64 | {%- endif -%} 65 |
66 | {%- endif -%} 67 | 68 |
69 |
70 | {% endblock %} -------------------------------------------------------------------------------- /content/posts/2015-10-19-mobile-c-sharp-workshop-17-oct-2015.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Mobile C# developer kick-off (17-oct-2015) 4 | date: 2015-10-19 22:00:00 5 | author: Antonio Feregrino 6 | categories: netduino c# 7 | summary: Este es un post de recapitulación del evento Mobile C# developer kick-off del 17 de octubre en la ESCOM 8 | lang: es 9 | featured_image: event.png 10 | images_folder: commons/ 11 | tags: Xamarin, Events 12 | featured_tag: Xamarin 13 | --- 14 | 15 | Este es un post para recapitular lo visto en el evento llevado a cabo en la Escuela Superior de Cómputo. 16 |
17 | En este repositorio de git está el código de la aplicación desarrollada durante el taller aquí está la explicación del algoritmo de Levenshtein y la implementación usada en C#. 18 |
19 | Esta es el post en el blog de Miguel de Icaza en donde habla sobre Mono en el PS4. 20 |
21 | De los plugins y extensiones: 22 | 30 |
31 | Para la gran mayoría que se quedó sin libro, no olviden el reto de la Sharpuladora y si aún así no se resisten las ganas de tenerlo, acá está la versión electrónica. 32 | 33 |
34 | Por cierto, pueden acceder a la Xamarin University a tomar unas clases de prueba. 35 |
36 | De nuevo no olviden consultarme si tienen dudas o problemas. -------------------------------------------------------------------------------- /templates/video.html: -------------------------------------------------------------------------------- 1 | {% extends framework %} 2 | 3 | {% block framework_content %} 4 |
5 |
6 | 7 | {%- assign banner = post.extras['banner'] -%} 8 | {%- assign banner_html = post-header.html -%} 9 | 10 | {%- if banner == nil -%} 11 | {%- include includes/views/post-header.html -%} 12 | {%- endif -%} 13 | 14 |
15 |
16 | {% block post_content %} 17 | {% endblock %} 18 |
19 |
20 | 21 | {%- assign result = hidden | where_exp: "item", "item == 'navigator'" -%} 22 | {%- if result.size == 0 -%} 23 |
24 | {%- if page.previous -%} 25 | 26 | {%- else -%} 27 | 28 | {%- endif -%} 29 | 30 | {%- if page.next -%} 31 | 32 | {%- else -%} 33 | 34 | {%- endif -%} 35 |
36 | {%- endif -%} 37 | 38 | {%- assign result = hidden | where_exp: "item", "item == 'related_posts'" -%} 39 | {%- if result.size == 0 -%} 40 |
41 |
Related Articles
42 | 48 |
49 | {%- endif -%} 50 | 51 | {%- assign result = hidden | where_exp: "item", "item == 'comments'" -%} 52 | {%- if result.size == 0 -%} 53 |
54 | {%- if page.comments != false -%} 55 | 56 | {%- if site.disqus.shortname -%} 57 | {%- include includes/extensions/comments/disqus.html -%} 58 | {%- endif -%} 59 | 60 | {%- if site.gitment.username -%} 61 | {%- include includes/extensions/comments/gitment.html -%} 62 | {%- endif -%} 63 | 64 | {%- endif -%} 65 |
66 | {%- endif -%} 67 | 68 |
69 |
70 | {% endblock %} -------------------------------------------------------------------------------- /templates/includes/extensions/seo.html: -------------------------------------------------------------------------------- 1 | {% if post %} 2 | {{ post.title }} | {{ site.title }} 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | {% else %} 26 | {{ site.title }} - {{ site.subtitle }} 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | {% endif %} -------------------------------------------------------------------------------- /templates/includes/views/header.html: -------------------------------------------------------------------------------- 1 | {%- if banner and header_transparent -%} 2 | {%- assign header_transparent_class = "site-header-transparent" -%} 3 | {%- endif -%} 4 | 5 | 40 | 41 | 75 | -------------------------------------------------------------------------------- /content/posts/tv/2016-09-26-martillo-dorado.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: El martillo dorado 3 | slug: martillo-dorado 4 | date: 2016-09-26 18:00:00 5 | youtube_id: 52VgvMQWydA 6 | images_folder: /tv/golden-hammer/ 7 | summary: La falacia del martillo de oro es una de las falacias en las cuales los desarrolladores caemos con mayor facilidad, esta implica el propner una única solución para distintos tipos de problemas. Estas "soluciones" pueden ser un IDE, un patrón de diseño o hasta un lenguaje de programación. 8 | featured_image: featured.jpg 9 | tags: Meta, YouTube 10 | featured_tag: Tv 11 | layout: video 12 | --- 13 | 14 | El Martillo Dorado, Martillo de Maslow, La ley del Instrumeto o *Per simplex responsum* es una falacia lógica en la cual se cae cuando se usa la misma respuesta (o alguna forma de esta) para cualquier pregunta o problema, incluyendo aquellas para las que no es la mejor solución o, peor aún: para las que ni siquiera lo es. 15 | 16 | Seguramente has escuchado alguna de estas frases: 17 | 18 | > Supongo que es tentador, si la únca herramienta que tienes es un martillo, tratar todo como si fuera un clavo - [Abraham Maslow](https://books.google.com.mx/books?id=3_40fK8PW6QC&printsec=frontcover#v=onepage&q=Hammer&f=false) 19 | 20 | > Dale un martillo a un niño pequeño y este encontrará que todo lo que encuentra necesita ser golpeado - [Abraham Kaplan](https://books.google.com.mx/books?id=OYe6fsXSP3IC&pg=PA28&dq=%22law+of+the+instrument%22+inauthor:kaplan&redir_esc=y#v=onepage&q=%22law%20of%20the%20instrument%22%20inauthor%3Akaplan&f=false) 21 | 22 | O básicamente cualquiera con esta forma 23 | 24 | > Si todo lo que tienes es un martillo, todo parece un clavo. 25 | 26 | El problema con la falacia del martillo dorado es no todo es un clavo, en otras palabras: no hay una solución que resuelva todos los problemas. 27 | 28 | ## ¿Qué tiene que ver con el desarrollo de aplicaciones? 29 | 30 | He hecho algunos vídeos hablando sobre tecnologías de desarrollo y patrones de diseño. Y es con ellos que nosotros, los desarrolladores/arquitectos/ingenieros de software, podemos incurrir en la falacia del martillo dorado. Y es que aplicar el patrón MVVM o la Inyección de Dependencias no es la solución para todas las aplicaciones… y Xamarin.Forms no es siempre la mejor opción para desarrollar aplicaciones móviles. 31 | 32 | ## ¿Qué nos lleva a querer usar el martillo para todo? 33 | Puede ser porque estamos muy familiarizados en alguna tecnología y se nos hace sencillo realizar estimaciones o planear sobre algo ya conocido. Otra razón es porque no conocemos otras alternativas y peor aún, porque las vemos como riesgosas sin conocerlas. Bajo estas condiciones es posible pensar en usar el martillo para todo. 34 | 35 | La solución es sencilla, aunque puede llevar un poco de tiempo, ya que consiste en ampliar nuestro conocimiento través de cursos, libros, escuela y lo más importante: **la práctica** con otras herramientas. -------------------------------------------------------------------------------- /templates/includes/extensions/code-highlight.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 7 | 8 | {%- assign name = 'code_badge.enabled' -%} 9 | {%- include includes/functions/get_value.html default='true' -%} 10 | {%- assign badge_enabled = return -%} 11 | 12 | {%- assign name = 'code_badge.color' -%} 13 | {%- include includes/functions/get_value.html default='#fff' -%} 14 | {%- assign badge_color = return -%} 15 | 16 | {%- assign name = 'code_badge.background_color' -%} 17 | {%- include includes/functions/get_value.html default='#ff4e00' -%} 18 | {%- assign badge_background_color = return -%} 19 | 20 | {%- assign name = 'code_badge.text_transform' -%} 21 | {%- include includes/functions/get_value.html default='uppercase' -%} 22 | {%- assign badge_text_transform = return -%} 23 | 24 | 70 | 71 | 92 | -------------------------------------------------------------------------------- /content/posts/tv/2018-03-20-programar-ingles.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ¿Programar en inglés? 3 | date: 2018-03-20 18:00:00 4 | youtube_id: UvaZZi_zgSo 5 | summary: Tu, ¿programas en inglés? 6 | tweet_id: 976181727671603200 7 | lang: en 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | Los algoritmos voraces o *greedy* son algoritmos que implementan una heuristica(técnica) que tiene como objetivo optimizar la búsqueda de una solución óptima para un problema. 14 | 15 | La idea detrás de los algoritmos voraces (o greedy) consiste en siempre tomar la mejor decisión de todas las que puede tomar en ese momento, con la esperanza de que al juntar todas estas pequeñas mejores decisiones, se obtendrá la mejor solución al problema en general. 16 | 17 | Seguramente verán esto explicado como que el algoritmo toma decisiones localmente óptimas con la esperanza de que esto lo llevará a la solución solución globalmente óptima. 18 | 19 | Toma por ejemplo este problema, supón que existen estas ciudades, y tu tarea es gastar lo menos posible en llegar de Pueblo Paleta a X, a Y, como puedes ver, hay muchas rutas. Un algoritmo voraz haría algo como esto: 20 | 21 | A cada paso, comprar el boleto más barato hasta llegar al pueblo Y. 22 | 23 | ### No siempre es lo mejor 24 | 25 | Como lo dije, el algoritmo tiene la esperanza de que al hacer esto va a obtener el mejor resultado al final, pero esto no necesariamente es así. 26 | 27 | Imagina un escenario como el anterior, pero con los precios un poco diferentes. Siguiendo la heurística voraz, un algoritmo haría algo como esto: 28 | 29 | Tomando nuevamente el boleto más barato, aunque al final, estas decisiones localmente óptimas lo llevaron a gastar más dinero. 30 | 31 | 32 | ### ¿Por qué existen? 33 | Pero bueno, si al final puede que no obtenga el mejor resultado, ¿por qué existe esta técnica? 34 | 35 | Pues hay problemas para los calcular la solución globalmente óptima es algo inimaginable, o increíblemente difícil como es el caso del problema del agente viajero (del cuál les hablé en un video anterior). Y tu como desarrollador tienes que tomar la decisión entre sacrificar un poco la optimalidad de tu algoritmo por el tiempo de procesamiento. 36 | 37 | También existen porque en general son sencillos de entender y también sencillos de programar. 38 | 39 | Recuerda que no existe un martillo dorado que sea la solución a todos los problemas que te encuentres, y que este esta es una de esas herramientas que puedes usar. 40 | 41 | ### Los componentes 42 | Ahora, no todos los problemas son susceptibles de afrontarse con este tipo de algoritmos, para que un problema pueda ser resuelto usándoles un algoritmo con esta característica debe tener: 43 | 44 | - El problema debe poder ser descompuesto en subproblemas sequenciales, y cada que uno de estos problemas se resuelve, (es decir, a cada decisión que se toma contribuye al resultado final, reduciendo el tamaño del problema. 45 | 46 | ### Ejemplos 47 | Entre los ejemplos que encontrarán sobre problemas que se pueden afrontar con estos algoritmos están: 48 | 49 | Problema del agente viajero, los de Minimumm Spanning Tree de Prim y Kruskal, la codificación de Huffman y el problema de la mochila Knapsack. -------------------------------------------------------------------------------- /static/assets/02/NumPy.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /content/posts/tv/2018-03-11-algoritmos-voraces.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Los algoritmos voraces 3 | date: 2018-03-11 18:00:00 4 | youtube_id: DsS33DCWvC4 5 | summary: La idea detrás de los algoritmos voraces (o greedy) consiste en siempre tomar la mejor decisión de todas las que puede tomar inmediatamante con la esperanza de que al juntar todas estas pequeñas "mejores" decisiones, se obtendrá la mejor solución al problema en general. 6 | tweet_id: 973684466211282945 7 | lang: en 8 | tags: Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | Los algoritmos voraces o *greedy* son algoritmos que implementan una heuristica(técnica) que tiene como objetivo optimizar la búsqueda de una solución óptima para un problema. 14 | 15 | La idea detrás de los algoritmos voraces (o greedy) consiste en siempre tomar la mejor decisión de todas las que puede tomar en ese momento, con la esperanza de que al juntar todas estas pequeñas mejores decisiones, se obtendrá la mejor solución al problema en general. 16 | 17 | Seguramente verán esto explicado como que el algoritmo toma decisiones localmente óptimas con la esperanza de que esto lo llevará a la solución solución globalmente óptima. 18 | 19 | Toma por ejemplo este problema, supón que existen estas ciudades, y tu tarea es gastar lo menos posible en llegar de Pueblo Paleta a X, a Y, como puedes ver, hay muchas rutas. Un algoritmo voraz haría algo como esto: 20 | 21 | A cada paso, comprar el boleto más barato hasta llegar al pueblo Y. 22 | 23 | ### No siempre es lo mejor 24 | 25 | Como lo dije, el algoritmo tiene la esperanza de que al hacer esto va a obtener el mejor resultado al final, pero esto no necesariamente es así. 26 | 27 | Imagina un escenario como el anterior, pero con los precios un poco diferentes. Siguiendo la heurística voraz, un algoritmo haría algo como esto: 28 | 29 | Tomando nuevamente el boleto más barato, aunque al final, estas decisiones localmente óptimas lo llevaron a gastar más dinero. 30 | 31 | 32 | ### ¿Por qué existen? 33 | Pero bueno, si al final puede que no obtenga el mejor resultado, ¿por qué existe esta técnica? 34 | 35 | Pues hay problemas para los calcular la solución globalmente óptima es algo inimaginable, o increíblemente difícil como es el caso del problema del agente viajero (del cuál les hablé en un video anterior). Y tu como desarrollador tienes que tomar la decisión entre sacrificar un poco la optimalidad de tu algoritmo por el tiempo de procesamiento. 36 | 37 | También existen porque en general son sencillos de entender y también sencillos de programar. 38 | 39 | Recuerda que no existe un martillo dorado que sea la solución a todos los problemas que te encuentres, y que este esta es una de esas herramientas que puedes usar. 40 | 41 | ### Los componentes 42 | Ahora, no todos los problemas son susceptibles de afrontarse con este tipo de algoritmos, para que un problema pueda ser resuelto usándoles un algoritmo con esta característica debe tener: 43 | 44 | - El problema debe poder ser descompuesto en subproblemas sequenciales, y cada que uno de estos problemas se resuelve, (es decir, a cada decisión que se toma contribuye al resultado final, reduciendo el tamaño del problema. 45 | 46 | ### Ejemplos 47 | Entre los ejemplos que encontrarán sobre problemas que se pueden afrontar con estos algoritmos están: 48 | 49 | Problema del agente viajero, los de Minimumm Spanning Tree de Prim y Kruskal, la codificación de Huffman y el problema de la mochila Knapsack. -------------------------------------------------------------------------------- /content/posts/2015-10-22-arreglos-en-c-sharp-parte-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Arreglos en C# (multidimensionales escalonados) 4 | date: 2015-10-22 21:00:00 5 | author: Antonio Feregrino 6 | categories: aprende-csharp 7 | summary: Los arreglos escalonados (o jagged arrays) son los tipos de arreglos multidimensionales más conocidos, y es que también son compunes en otros lenguajes de programación. Un arreglo escalonado no es más que un arreglo de arreglos. 8 | lang: es 9 | featured_image: featured.png 10 | ideone: http://ideone.com/fork/0AAvgK 11 | tags: AprendeCSharp 12 | featured_tag: AprendeCSharp 13 | --- 14 | 15 | En el post anterior les contaba sobre los arreglos arreglos unidimensionales en C#, y hacia el final los invitaba a leer este, sobre los arreglos multidimensionales, así que sin más: 16 | 17 | Los arreglos escalonados (o *jagged arrays*) son los tipos de arreglos multidimensionales más conocidos, y es que también son compunes en otros lenguajes de programación. Un arreglo escalonado no es más que un arreglo de arreglos. 18 | 19 | #### Instanciación 20 | Para crear estos arreglos de arreglos, tenemos una sintaxis similar a la creación de arreglos unidimensionales, con `[ ]` para cada dimensión: 21 | ```csharp 22 | char[][] gato = new char[3][]; 23 | 24 | string [][][] rubik = new string[3][][]; 25 | 26 | int[][] escalera = new int[3][]; 27 | ``` 28 | Acá es importante notar que al instanciar un arraglo multidimensional de esta manera **únicamente estamos indicando el tamaño de la primera dimensión**, 3 en el caso de `gato`, 3 también para `rubik` y 2 para `escalera`. Es tarea nuestra inicializar los arreglos interiores: 29 | ```csharp 30 | for(int i = 0; i < 3; i++) 31 | { 32 | gato[i] = new char[3]; // gato[i] hace referencia a un arreglo 33 | } 34 | ``` 35 | ```csharp 36 | for(int i = 0; i < 3; i++) 37 | { 38 | rubik[i] = new string[3][]; 39 | for(int j = 0; j < 3; j++) 40 | { 41 | rubik[i][j] = new string[3]; 42 | } 43 | } 44 | ``` 45 | Con los arreglos escalonados no hay nada que nos prohíba crear arreglos internos de dimensiones iguales a la de arreglo que las contiene, es más, **podemos crear arreglos internos de distintos tamaños en la misma dimensión**, hagamos algo con nuestro arreglo `escalera`: 46 | ```csharp 47 | escalera [0] = new int[1] { 1 }; 48 | escalera [1] = new int[2] { 2, 3 }; 49 | escalera [2] = new int[3] { 4, 5, 6 }; 50 | ``` 51 | Con estos arreglos de arreglos también podemos usar la instanciación de colecciones: 52 | ```csharp 53 | char[][] gato = 54 | { 55 | new char[]{ 'o', 'x', 'o' }, 56 | new char[]{ 'o', 'x', 'o' }, 57 | new char[]{ 'o', 'x', 'o' } 58 | }; 59 | ``` 60 | 61 | #### Acceso a los elementos 62 | De nueva cuenta, y por tratarse de arreglos, usaremos los `[ ]` para acceder a los elementos de nuestros arreglos, de tal manera que es posible escribir algo como esto: 63 | ```csharp 64 | for (int i = 0; i < escalera.Length; i++) 65 | { 66 | for (int j = 0; j < escalera [i].Length; j++) 67 | { 68 | Console.Write (escalera[i][j] + " "); 69 | } 70 | Console.WriteLine(); 71 | } 72 | ``` 73 | 74 | #### Lo que sigue 75 | En el post siguiente les platicaré sobre los arreglos rectangulares, que son lo más parecido a matrices que podemos encontrar en C#. Estos son similares a los arreglos rectangulares con la pequeña diferencia de que no pueden contener arreglos de distintos tamaños dentro de la misma dimensión. -------------------------------------------------------------------------------- /content/posts/2015-07-12-bubble-display-netduino-plus-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Conectando un Bubble Display a un Netduino Plus 2 4 | date: 2015-07-17 18:31:38 5 | author: Antonio Feregrino 6 | categories: netduino c# 7 | summary: Para un proyecto Instrumentación en la escuela decidí desempolvar mi Netduino Plus 2, en el proyecto decesitábamos mostrar las mediciones de tres distintos sensores en un par de displays de 7 segmentos. 8 | lang: es 9 | featured_image: featured.png 10 | alias: /bubble-display-netduino-plus-2/index.html 11 | tags: Netduino 12 | featured_tag: Netduino 13 | --- 14 | 15 |

Para un proyecto Instrumentación en la escuela decidí desempolvar mi Netduino Plus 2, en el proyecto decesitábamos mostrar las mediciones de tres distintos sensores en un par de displays de 7 segmentos, para ello decidí comprar un Bubble Display que no trae 2 sino 4 displays de 7 segmentos en un encapsulado muy estético. Al principio no tenía ni la menor idea de cómo cablearlo, pero consultando el datasheet resultó sencillo.

16 |

Material

17 |

Además del Bubble Display, también usé 7 resistencias de 330 Ω, 4 de 1kΩ y 4 transistores BC557. 18 | El bubble display no necesita explicación, en México lo compré aquí. Las resistencias de 330 son para no dañar el display (se conectan entre este y la tarjeta del Netduino), las resistencias de 1k se usan para la misma razón pero conectado a los transistores mientras que los transistores se emplean como switches que permiten el flujo de la corriente a tierra ya que el display es de cátodo común.

19 | 20 |

Programación

21 |

La parte que más me agrada de esto es la programación, para hacer uso del display, cree una clase llamada Bubble7 a través de la cual se pude interactuar con el display y cada uno de sus segmentos. El constructor de la clase recibe como parámetros los pines a los que está conectado display y los transistores.

22 | 23 |

Expone varios métodos, entre ellos el de display imprimir un dígito PrintDigit, también es importante el método TurnOnDisplay ya que con este se indica qué display estará activo y mostrará datos. Para crear el efecto de que todos los displays están encendidos a la vez, debe existir un retardo muy pequeño entre que se enciende un display mostrando un número y otro, como se muestra en el método ShowNumber. La clase está en GitHub para su descarga, acá pongo una muestra de cómo se peuede usar para implementar un contador.

24 | 25 | ```csharp 26 | public class Program 27 | { 28 | public static void Main() 29 | { 30 | Bubble7 bubble = new Bubble7(Pins.GPIO_PIN_D0, Pins.GPIO_PIN_D1, 31 | Pins.GPIO_PIN_D2, Pins.GPIO_PIN_D4, Pins.GPIO_PIN_D3, 32 | Pins.GPIO_PIN_D6, Pins.GPIO_PIN_D5, Pins.GPIO_PIN_D7, 33 | Pins.GPIO_PIN_D8, Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D10); 34 | 35 | int count = 0; 36 | while (true) 37 | { 38 | if (count == 9999) 39 | count = 0; 40 | bubble.ShowNumber(count++); 41 | } 42 | } 43 | } 44 | ``` 45 |

Sugerencia de armado

46 |
Bubble Display set up
-------------------------------------------------------------------------------- /content/posts/2015-10-23-arreglos-en-c-sharp-parte-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Arreglos en C# (multidimensionales rectangulares) 4 | date: 2015-10-23 22:00:00 5 | author: Antonio Feregrino 6 | categories: aprende-csharp 7 | summary: A diferencia de los arreglos escalonados, los rectangulares son lo más parecido a matrices que podemos encontrar en C#. 8 | lang: es 9 | ideone: http://ideone.com/fork/8C2iOj 10 | featured_image: featured.png 11 | tags: AprendeCSharp 12 | featured_tag: AprendeCSharp 13 | --- 14 | 15 | Después de conocer los arreglos multidimensionales escalonados esta vez toca el turno de conocer otro tipo de arrelgos multidimensionales en C#: Los rectangulares. En pocas palabras podríamos decir que estos no son "arreglos de arreglos", sino que en realidad son matrices dado que no es posible declarar arreglos dentro de ellos como con los escalonados. 16 | 17 | #### Instanciación 18 | Como con todos los tipos por referencia podemos usar la palabra reservada `new` para instanciar estos arreglos, aunque esta vez es necesario incluír una coma `,` para separar las dimensiones en lugar de los corchetes cuadrados de manera consecutiva, es decir, si quiero algo de dos dimensiones en lugar de `[][]` debemos escribir `[,]`: 19 | ```csharp 20 | char [,] gato = new char[3, 3]; 21 | 22 | string [,,] rubik = new string[3, 3 ,3]; 23 | 24 | int [,,,] laMatrix = new int[8, 2, 7, 6]; 25 | ``` 26 | Para este tipo de arreglos **siempre es necesario precisar el tamaño de todas las dimensiones**, ya que el espacio es asignado durante la asignación, a diferencia de los arreglos escalonados. El compilador nos indicará algún error si no utilizamos la misma cantidad de elementos para cada dimensión: 27 | ```csharp 28 | char [,] gato = // new char[3, 3] // El new es opcional 29 | { 30 | { 'x', 'o', 'x' }, 31 | { 'o', 'x', '-' }, 32 | { 'x', 'o', 'x' }, 33 | }; 34 | 35 | // Error de compilación, para 'gatoMalo' los arreglos internos deben ser de 2 elementos 36 | char [,] gatoMalo = 37 | { 38 | { 'x', 'x' }, 39 | { 'o', 'x', 'x' }, 40 | { 'o', 'x' }, 41 | }; 42 | ``` 43 | 44 | #### Acceso a los elementos 45 | Para acceder a los elementos debemos recurrir a la combinación de `[]` y `,`, también es importante recordar que los arreglos están indizados en `0`. 46 | ```csharp 47 | Console.WriteLine( gato[0,0] ); // 'x' 48 | 49 | gato[1,2] = 'y'; 50 | Console.WriteLine( gato[1,2] ); // 'y' 51 | ``` 52 | 53 | #### Propiedades y métodos 54 | Al contrario de los otros arreglos, en este caso una llamada a la propiedad `Length` nos devolverá la cantidad **total** de elementos dentro del arreglo, en lugar de la cantidad de elementos dentro de esa dimensión, por ejemplo: 55 | ```csharp 56 | Console.WriteLine(gato.Length); // 9 = 3 x 3 57 | 58 | Console.WriteLine(rubik.Length); // 27 = 3 x 3 x 3 59 | 60 | Console.WriteLine(laMatrix.Length); // 672 = 8 x 2 x 7 x 6 61 | ``` 62 | Si lo que queremos es conocer el tamaño de determinada dimensión, es necesario hacer una llamada al método `GetLength` e indicando la dimensión a consultar 63 | ```csharp 64 | Console.WriteLine( "D0: " + laMatrix.GetLength(0) ); // 8 65 | Console.WriteLine( "D1: " + laMatrix.GetLength(1) ); // 2 66 | Console.WriteLine( "D2: " + laMatrix.GetLength(2) ); // 6 67 | Console.WriteLine( "D3: " + laMatrix.GetLength(3) ); // 7 68 | ``` 69 | 70 | #### Lo que sigue 71 | En siguientes posts conitnuaré hablando sobre C#, en particular de clases, métodos y parámetros, ¿quieres conocer sobre algo en específico? mándame un tweet o un correo electrónico ;) -------------------------------------------------------------------------------- /content/posts/tv/2017-05-16-autorizacion-autenticacion.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Identidad, autenticación y autorización 3 | slug: autorizacion-autenticacion 4 | date: 2017-05-16 18:00:00 5 | youtube_id: LhxWy_I3EKM 6 | images_folder: /tv/auth/ 7 | summary: Identidad, Autenticación y Autorización son conceptos distintos, pero que juntos forman una parte importantísima de la seguridad en una aplicación. 8 | featured_image: featured.jpg 9 | tags: Meta, YouTube 10 | featured_tag: Tv 11 | layout: video 12 | --- 13 | 14 | Estoy seguro que con la identidad no hay mucho problema, sino que es con la autenticación y la autorización en donde existe un pequeño conflicto ya que al igual que la internacionalización y localización, suelen usarse indistintamente, haciendo que el que hable de ellos caiga en un pequeño error. 15 | 16 | ## Identidad 17 | Sucede cuando yo digo, soy Antonio Feregrino alumno del Instituto Politécnico Nacional. O cuando tu vas a la página de Gmail y escribes tu correo electrónico. Es decir, tanto yo al decir mi nombre como tu al poner tu correo estamos afirmando que poseemos cierta identidad. Corresponderá al sistema (o a la escuela) confirmar la veracidad de esta afirmación mediante la autenticación. 18 | 19 | 20 | ## Autenticación 21 | La autenticación es un proceso mediante el cual un usuario (humano o no humano) confirma que le pertenece determinada identidad en un sistema. 22 | 23 | Siguiendo el ejemplo de tu correo electrónico, para autenticarte bastaría con que escribieras tu contraseña (a menos que estés utilizando autenticación de dos pasos) para verificar que el correo te pertenece. Yo, por otro lado, tengo una credencial que me acredita como estudiante del Instituto Politécnico Nacional, entonces cuando dentro del campus alguien me solicita identificarme, basta con mostrar esta credencial para estar "autenticado". 24 | 25 | Sin embargo, esta era solo mi credencial de acceso a la escuela, para acceder a otros servicios de mi escuela como el préstamo de libros de la biblioteca o la alberca necesitaba otro tipo de credenciales. Es entonces cuando la autorización entra en juego. 26 | 27 | ## Autorización 28 | 29 | La autorización es el proceso mediante el cual se establece a qué recursos un usuario tiene permitido acceder. Para esto es cuando entra en juego la autorización, yo podría tener una credencial que me autorice a sacar libros de la biblioteca y otra que me permita hacer uso de la alberca. 30 | 31 | Es decir, no porque yo esté autenticado voy a tener acceso a todos los recursos de la escuela. Usualmente el nivel de acceso se controla mediante la asignación de roles, perfiles o facultades, para facilitar así la tarea a los encargados de administrar el sistema. 32 | 33 | ## La raíz de la confusión 34 | 35 | Creo que mucha de la confusión de estos términos proviene de que estamos muy familiarizados con sistemas que pareciera que no ejecutan un proceso de autorización, como por ejemplo el de tu correo electrónico personal, una vez que consigues entrar puedes hacer y deshacer a tu gusto. Sin embargo, sí ocurre la autorización, solo que para tu fortuna, estás autorizado para hacer lo que quieras. 36 | 37 | Ah, y no es necesario que exista autenticación para que exista autorización. Piensa en la mayoría de tiendas en línea: Estas no te piden que inicies sesión para ver los productos que ofrecen, podríamos decir que sin autenticarte únicamente tienes autorización de solo lectura. 38 | 39 | En resumen: Identidad, Autenticación y Autorización son conceptos distintos, pero que juntos forman una parte importantísima de la seguridad en una aplicación. 40 | -------------------------------------------------------------------------------- /templates/includes/extensions/theme-toggle.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 10 |
11 | 12 | {%- assign name = 'night_mode' -%} 13 | {%- include includes/functions/get_value.html default='auto' -%} 14 | {%- assign night_mode = return -%} 15 | 16 | 109 | -------------------------------------------------------------------------------- /content/posts/tv/2017-02-14-apis.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: API 3 | slug: apis 4 | date: 2017-02-14 18:00:00 5 | youtube_id: 4VcpwTSFcyI 6 | images_folder: /tv/api/ 7 | summary: Las interfaces de programación de aplicaciones, son un elemento vital del desarrollo de sistemas de software, y aunque desde casi siempre han existido entre nosotros, no es sino hasta últimamente que la "popularidad" de esta palabra ha aumentado gracias a los servicios web y las aplicaciones móviles. 8 | featured_image: api_thumb.png 9 | tags: Meta, YouTube 10 | featured_tag: Tv 11 | layout: video 12 | --- 13 | 14 | Las interfaces de programación de aplicaciones o (*application programming interfaces*), son un elemento vital del desarrollo de sistemas de software, y aunque desde casi siempre han existido entre nosotros, no es sino hasta últimamente que la "popularidad" de esta palabra ha aumentado gracias a los servicios web y las aplicaciones móviles. 15 | 16 | La clave para entender qué es una API radica en entender qué es una interfaz: Podemos ver una interfaz como un contrato entre dos partes, en el cual una establece las condiciones de la relación, en este caso, la interfaz especifica qué métodos, funciones, propiedades, recursos… estarán disponibles para ser usados. 17 | 18 | Este tipo de contratos se establecen básicamente para lo mismo que en la vida cotidiana: para solicitar los servicios de un tercero y realizar una acción que sería de otro modo, tedioso, complicado. Para poner un ejemplo: tan solo basta con recordar cómo funciona la computadora: con código máquina, te imaginas lo tedioso (y tardado) que sería escribir un programa actual con código máquina… entonces nosotros no tenemos mas que agradecer a la gente que se dispuso a crear lenguajes como el ensamblador que no es más que una especie de interfaz para interactuar con la computadora, sin necesidad de escribir (y seguramente equivocarnos) si usáramos código máquina. Así mismo, podemos ver lenguajes de alto nivel como interfaces hacia el procesador. 19 | 20 | Seguramente hasta personas no tienen conocimiento de programación tienen una pequeña noción del lo que es la interfaz interfaz, con tan solo ver algunas de las aplicaciones existentes en tu escritorio o que usas en el celular, en ellas existe **interfaz** grafica de una app que es un medio de interacción que permite acceder a los recursos de una computadora a través mediante un medio "amigable" para el usuario. De la misma manera en que facebook permite consultar la lista de amigos de una persona con tan solo llamar a una dirección http. O de la misma manera que Java permite abrir un Socket de tu computadora sin necesiddad de que tu te peleees con puertos, direcciones MAC. 21 | 22 | El concepto de API es muy usado además en la programación orientada objetos, ya que mediante las APIS se puede encapsular el funcionamiento de un objeto y permitir que con este se interactua a través de un set predefido de operaciones. Como es el caso de los métodos disponibles en cualquier clase de Java, C# y demás. Es más, cualquier librería, framework o servicio que uses cuenta con una API que nos permite acceder a sus recursos e interactuar con ella. 23 | 24 | Para ejemplos de interfaz tenemos la API de Twitter, la cual se invoca a través de peticiones HTTP. La API de Java y como ejemplo estrella la API de YouTube tiene una API, que me permite crear una aplicación en C# que suba un video como el que acabas de ver. 25 | 26 | En el video hago mención a un sitio web que almacena referencias a muchísimas API, el sitio es este https://www.programmableweb.com -------------------------------------------------------------------------------- /content/posts/2015-09-16-creando-propios-alias.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Creando nuestros propios alias 4 | date: 2015-09-16 13:00:00 5 | author: Antonio Feregrino 6 | categories: c-sharp 7 | summary: Hace poco vimos que existen alias en C# para los tipos predefinidos de datos, y hasta ahí todo claro. Pero nosotros como programadores también podemos beneficiarnos de crear nuestros propios alias. 8 | lang: es 9 | featured_image: featured.jpg 10 | github: https://gist.github.com/fferegrino/a81cd436e4d631f1cf4d 11 | alias: /creando-propios-alias/index.html 12 | tags: AprendeCSharp 13 | featured_tag: AprendeCSharp 14 | --- 15 | 16 | Hace poco vimos que existen alias en C# para los tipos predefinidos de datos, y hasta ahí todo claro. Pero nosotros como programadores también podemos beneficiarnos de crear nuestros propios alias. Hay dos maneras de hacer uso de los alias: 17 | 18 | ### Para tipos de dato 19 | ¿No sería fabuloso poder "cambiarle" (entre comillas porque en realidad solamente le estamos dando otro nombre) el nombre a int? tal vez sea mejor ponerle algo como Entero. Lo podemos hacer con una sentencia using de la siguiente manera: 20 | ```csharp 21 | using Entero = System.Int32; 22 | ``` 23 | Y después usarlo de la siguiente manera: 24 | ```csharp 25 | Entero uno = 1; 26 | Entero dos = 2; 27 | Console.WriteLine(uno + dos); // Imprimirá 3 28 | ``` 29 | Pero bueno, no creo que cambiarle el nombre a un entero les haga mucho sentido, así que trasladémoslo a una aplicación real. Supongamos que tenemos una aplicación que separa el modelo del acceso a datos, dentro de ella también tenemos dos clases llamadas Person, una dentro del namespace MyApp.DataAccess.Entities y otra dentro de MyApp.ViewModels.Editable. Para que la aplicación funcione hay un punto en el que ambas clases deben coincidir para que *mapear* de una a otra. Sin alias tendríamos que usar el nombre completo de las clases: 30 | ```csharp 31 | public static MyApp.DataAccess.Entities.Person MapPerson(MyApp.ViewModels.Editable.Person person) 32 | { 33 | // ... 34 | ``` 35 | Ahora, usando alias reemplazaremos los nombres por algo más corto (y probablemente amigable): 36 | ```csharp 37 | using EntityPerson = MyApp.DataAccess.Entities.Person; 38 | using EditablePerson = MyApp.ViewModels.Editable.Person; 39 | // ... ... ... 40 | public static EntityPerson MapPerson(EditablePerson person) 41 | { 42 | // ... 43 | ``` 44 | ### Para nombres de espacio 45 | Hay que aceptarlo, cambiar el nombre de los tipos puede resultar un poco confuso, pero C# también nos ofrece la posibilidad de ponerle un alias a los *namespaces* y se hace de la misma manera que para los tipos de dato: 46 | ```csharp 47 | using Ents = MyApp.DataAccess.Entities; 48 | using Edt = MyApp.ViewModels.Editable; 49 | // ... ... ... 50 | public static Ents.Person MapPerson(Edt.Person person) 51 | { 52 | // ... 53 | ``` 54 | ### Gran, gran desventaja 55 | Dejé lo peor para el final: Los alias creados por nosotros solamente son válidos dentro del bloque de código en el que los definamos, ya sea dentro de un namespace o dentro de un archivo completo, lo cual significa que tenemos que repetirlo para cada archivo en el que lo usemos. Sería muy útil poderlos definir una sola vez a nivel global y después poder usarlas en toda nuestra aplicación. 56 | 57 | #### Mi consejo 58 | Estos alias existen, pero yo procuro no usarlas salvo en casos extremos y es que si no se usan con moderación pueden complicar mucho la lectura del código. 59 | 60 | -------------------------------------------------------------------------------- /content/posts/2015-11-16-code-organization-visual-studio.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: How is my code organized in Visual Studio? 4 | date: 2015-11-16 21:00:00 5 | author: Antonio Feregrino 6 | featured_image: featured.jpg 7 | categories: xamarin 8 | tweet_id: 667177573508608000 9 | lang: en 10 | summary: If you have ever used an IDE to develop any application you might have wondered how do these kind of programs know where are the components for each one of the things that make your app compile or run. In this post I'll try to explain how Xamarin Studio and Visual Studio keeps that control. 11 | tags: VisualStudio, Xamarin 12 | featured_tag: VisualStudio 13 | --- 14 | 15 | If you have ever used an IDE to develop any application you might have wondered how do these kind of programs know where are the components for each one of the things that make your app compile or run. In this post I'll try to explain how Xamarin Studio and Visual Studio keeps that control. 16 | 17 | ### The Solution 18 | Both Visual Studio and Xamarin Studio organize our code, assets, libraries and other stuff in a structure called *Solution*, all this information is stored within a file with extension **.sln**. The **.sln** file is an (usually) automatically generated plain text file that tells the IDE where to find the projects related to our application. 19 | 20 | 21 | 22 | This is how a Solution (the free C#/F# shirt app solution) looks like when opened in Xamarin Studio and Visual Studio: 23 | 24 | 25 | 26 | And this is how a the same file looks like when opened in a plain text editor. 27 | 28 | 29 | 30 |
31 |
1. Solution
32 |
The file itself, the name we see in the IDE is the same name of the file plus the .sln extension.
33 |
2. Solution folder
34 |
These are logical folders that we can use to organize our solution.
35 |
3. Shared project
36 |
A shared project (we'll talk about them on a later post).
37 |
4. C# project
38 |
A C# project, in this case refers to an Android project, in Xamarin is a convention to use the .Droid suffix to denote that.
39 |
5. C# project
40 |
Another C# project, in this case refers to an iOS project, in Xamarin is a convention to use the .iOS suffix to denote that.
41 |
42 | 43 | 44 | ### The .[something]proj file 45 | 46 | As I mentioned above, the Solution keeps track of the projects that comprise our application, but what is exactly a project? 47 | 48 | Well, a Project is a logical way to organize a project's files (classes, resources, images...) it is described in a file ending with `proj`, being `.csproj` for C# projects, `.shproj` for shared, other kind of projects end in `.vbproj`, `.jsproj`, etc. 49 | 50 | As you can see in the previous image, the `.sln` file contains "links" to these projects. 51 | 52 | These are the projects for the Free Xamarin Shirt App: 53 | 54 | 55 | 56 | ### tl;dr 57 | We can explain how is our code organized with a simple diagram. 58 | 59 | 60 | -------------------------------------------------------------------------------- /content/posts/2015-10-05-tipos-dato-c-sharp.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Tipos de dato en C# 4 | date: 2015-10-05 22:00:00 5 | author: Antonio Feregrino 6 | categories: aprende-csharp 7 | summary: Para la mayoría de sus aplicaciones, C# es un lenguaje fuertemente tipado, en este post presento dos categorías de tipos que nos podemos encontrar cuando trabajamos con este lenguaje. 8 | lang: es 9 | featured_image: featured.jpg 10 | alias: /tipos-dato-c-sharp/index.html 11 | tags: AprendeCSharp 12 | featured_tag: AprendeCSharp 13 | --- 14 | 15 | Para fines de este post, diremos que C# es un lenguaje fuertemente tipado (aunque ya permite tipado dinámico y eso lo palticaré en otro post), lo que significa que cada variable, literal o constante debe tener un tipo declarado y dicho tipo no cambiará con el flujo del programa. Dentro de los tipos que ofrece C#, podemos encontrar dos grandes categorías: 16 | 17 | ### Predefinidos 18 | Son los tipos que el lenguaje incorpora para almacenar valores comunes, entre ellos: 19 | 20 | - `bool` para valores binarios, como un *sí* o *no*, o `1` o `0` 21 | - `int` para valores enteros, que puede ir de `-2,147,483,648` a `2,147,483,647` 22 | - `char` para caracteres como `a`, `@` o `%` 23 | - `string` para una secuencia de caracteres 24 | 25 | La lista la completan: `byte`, `decimal`, `float`, `long`, `sbyte`, `short`, `uint`, `ulong`, `ushort` y `object`. 26 | 27 | A partir de estos tipos de dato se pueden crear otros tipos con la finalidad de satisfacer nuestras necesidades. 28 | 29 | ### Compuestos 30 | Los tipos compuestos están formados a partir de los tipos predefinidos y nos ayudarán a modelar de manera más real los problemas con los que nos encontremos. Estos se crean usando las palabras reservadas `interface`, `struct`, `enum` y `class`. 31 | 32 | Otra clasificación que podemos definir, es la siguiente, que clasifica los tipos de dato de acuerdo a como se gestionan en la memoria: 33 | 34 | ### Referencia 35 | Se almacena en ellos una referencia a los datos, por ejemplo un tipo de dato `class` o `string`. 36 | 37 | ### Valor 38 | Almacenan el valor del dato por completo, por ejemplo `struct` y `enum`. 39 | 40 | ## Ejemplo 41 | Para ilustrar esta última categoría, tomemos el siguiente ejemplo: 42 | 43 |
44 |
45 | ```csharp 46 | struct Tiempo 47 | { 48 | public int Minutos; 49 | public int Horas; 50 | } 51 | // ... 52 | Tiempo t1 = new Tiempo(); 53 | Tiempo t2 = t1; 54 | ``` 55 |
56 |
57 | ```csharp 58 | class Tiempo 59 | { 60 | public int Minutos; 61 | public int Horas; 62 | } 63 | // ... 64 | Tiempo t1 = new Tiempo(); 65 | Tiempo t2 = t1; 66 | ``` 67 |
68 |
69 |
70 |
71 | 72 |
73 |
74 | 75 |
76 |
77 |
78 | Las imagenes debajo de los códigos tienen la intención de mostrar una simple representación de lo que pasa al ejecutar el código. Al hacer `t2 == t1` sobre la estructura de Tiempo, al ser un un *tipo por valor* se crea una copia, lo cual significa que cualquier modificación que se haga a `t1` no provocará ningún cambio sobre `t2`. 79 | Por otro lado, en el caso de la clase Tiempo, si se hiciera alguna modificación sobre `t2`, `t1` también se vería afectado al ser un *tipo de referencia*. 80 | 81 |
82 | En futuros post seguré explorando algunos detalles escenciales de C#, como arreglos, métodos y clases. 83 | -------------------------------------------------------------------------------- /content/posts/tv/2016-04-18-ideone.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ideone 3 | date: 2016-04-18 18:00:00 4 | youtube_id: aVrqezV-4AA 5 | is_tv: true 6 | images_folder: /tv/ideone/ 7 | categories: c-sharp 8 | summary: Ideone es una colección de compiladores en línea, que permite escribir, compilar y ejecutar código fuente escrito en más de 60 lenguajes de programación. 9 | featured_image: featured.png 10 | tags: Meta, YouTube 11 | featured_tag: Tv 12 | layout: video 13 | --- 14 | 15 | Ideone es un compilador en línea una colección de compiladores en línea, que permite escribir, compilar y ejecutar código fuente escrito en más de 60 lenguajes de programación. Basta con entrar a la página web, escribir o copiar tu código dar click en *Run* y listo, el código se ejecuta. 16 | 17 | Hay una cantidad bastante grande de lenguajes con los que funciona, entre ellos C, C++, Java y, claro que sí, C#. 18 | 19 | 20 | 21 | ### ¿Es un IDE? 22 | El nombre puede resultar un poco confuso, y es que a pesar de lo que se podría pensar al ver solo el nombre (**IDE**one), no lo podemos comparar con otras herramientas como NetBeans o Visual Studio puesto que como se ve, únicamente tenemos acceso a un editor bastante sencillo de código y un botón de "Ejecutar". 23 | 24 | 25 | 26 | ### Entradas y salidas 27 | Para simular la entrada y salida estandar, digamos, el teclado y la pantalla, tenemos estas dos cajas de texto. La gran diferencia es que no es interactivo, tenemos que preeestablecer la entrada desde un inicio, en otras palabras, no existe interacción porque no puedes escribir al tiempo que se ejecuta tu prorgrama. 28 | 29 | ### ¿Qué se puede hacer con él? 30 | 31 | - Lo que se puede hacer con una aplicación de consola recién creada: salidas y entradas de texto. 32 | - Crear breves fragmentos de código y compartirlos con otras personas, ellos pueden ver el código, copiarlo y compilarlo. 33 | - Llevar un registro de los códigos que hemos creado, así como etiquetarlos para crear colecciones y tener un poco más de control sobre ellos. 34 | 35 | ### ¿Qué no se puede hacer con él? 36 | No podemos agregar una referencia a algo no incluído dentro de la especificación del compilador y esperar que el código compile, por ejemplo, si usas C# como lenguaje, no puedes agregar una referencia a un paquete de NuGet, o alguna otra librería externa. 37 | 38 | También se tiene que tomar en cuenta de que la ejecución se realiza en una “caja de arena” o *sandbox* para impedir que se acceda al sistema de archivos o se modifiquen cosas como el registro o el sistema operativo en el que los programas son ejecutadas. 39 | 40 | ## Ejemplos de uso 41 | 42 | - Probar ideas de código de manera rápida, por ejemplo, en el Club de Algoritmia de la ESCOM yo lo usaba para probar algunos programas y poder compartirlos con mis compañeros de equipo para darnos una idea de qué tan buena era nuestra solución. 43 | 44 | - Yo lo uso en el blog para algunos de mis posts, tal vez se hayan dado cuenta de que en algunos dentro de la sección de información, lo único que tienen que hacer es dar click justo encima del título del post y listo. 45 | 46 | 47 | 48 | - Se puede usar para empezar a programar en algún lenguaje sin necesidad de tener las herramientas instaladas en la computadora desde la que estemos trabajando. 49 | 50 | Te invito a que veas este ejemplo y te animes a usarlo. -------------------------------------------------------------------------------- /content/posts/2015-11-16-organizacion-codigo-visual-studio.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: ¿Cómo organiza mi código Visual Studio? 4 | date: 2015-11-18 21:00:00 5 | author: Antonio Feregrino 6 | featured_image: featured.jpg 7 | categories: xamarin 8 | summary: Si alguna vez has usado un IDE para desarrollar alguna aplicación tal vez te hayas preguntado cómo es que ese tipo de programas saben en dónde están los componentes para cada una de las cosas que hacen que tu app compile o funcione. 9 | tags: VisualStudio, Xamarin 10 | featured_tag: VisualStudio 11 | --- 12 | 13 | Si alguna vez has usado un IDE para desarrollar alguna aplicación tal vez te hayas preguntado cómo es que ese tipo de programas saben en dónde están los componentes para cada una de las cosas que hacen que tu app compile o funcione. En este post trataré de explicar cómo es que Xamarin y Visual Studio llevan este control. 14 | 15 | ### La "Solución" 16 | Tanto Visual Studio como Xamarin Studio organizan nuestro código *assets*, liberías y demás en una estructura llamada Solución (`Solution` en inlglés), todo está almacenado en un archivo que tiene una extensión `.sln`. Este archivo que le dice al IDE en dpnde están los proyectos de nuestra aplicación, es un archivo de texto plano, que es usualmente autogenerado por el entorno que estamos empleando para desarrollar. 17 | 18 | 19 | 20 | Así es como una *Solución* se ve cuando es abierta en Xamarin Studio y Visual Studio: 21 | 22 | 23 | 24 | Y así es como se ve el mismo archivo pero abierto en un editor de texto plano: 25 | 26 | 27 | 28 |
29 |
1. Solución
30 |
El archivo como tal, el nombre que vemos en el IDE es el mismo nombre del archivo más la extensión sln.
31 |
2. Carpeta de solución
32 |
Estas son carpetas lógicas que podemos usar para mejorar la organización de nuestro código.
33 |
3. Proyecto compartido
34 |
Un proyecto compartido... veremos más de el en un siguiente post.
35 |
4. Proyecto de C#
36 |
Un proyecto de C#, en este caso se refiere a un proyecyto de Android, en Xamarin es una convenciín usar el sufijo .Droid para este tipo de proyectos.
37 |
5. Proyecto de C#
38 |
Otro proyecto de C#, en este caso se refiere a un proyecyto de iOS, en Xamarin es una convenciín usar el sufijo .iOS para este tipo de proyectos.
39 |
40 | 41 | 42 | ### El archivo .[algo]proj 43 | 44 | Como mencioné anteriormente, la *solución* lleva un control de los proyectos que componen nuestra aplicación... pero, ¿qué es exactamente un proyecto? 45 | 46 | Bien, pues un proyecto es una manera lógica de organizar las clases, recursos imágenes necesarias para un cierto fin, este se describe en un archivo con extensión que termina en `proj`, siendo `.csproj` para proyectos C#, `.shproj` para proyectos compartidos y, por ejemplo, otros terminan en `.vbproj`, `.jsproj`, etc. 47 | 48 | Como puedes ver en la imagen anterior, el archivo `.sln` contiene una especie de enlaces a esos proyectos. 49 | 50 | Estos son los proyectos de la *Free Xamarin Shirt App*: 51 | 52 | 53 | 54 | ### tl;dr 55 | Podemos explicar cómo es que está organizado nuestro código con el siguiente diagrama: 56 | 57 | 58 | -------------------------------------------------------------------------------- /content/posts/tv/2016-08-10-programar-con-estilo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Programando con estilo 3 | slug: programar-con-estilo 4 | date: 2016-08-10 18:00:00 5 | youtube_id: Htsknf4L2o4 6 | images_folder: /tv/estilo/ 7 | summary: Programar con estilo es escribir nuestros programas fáciles de entender, bien documentados y siguiendo convenciones de escritura previamente adoptadas. 8 | featured_image: featured.jpg 9 | tags: Meta, YouTube 10 | featured_tag: Tv 11 | layout: video 12 | --- 13 | 14 | Y no, el título no se refiero a escribir código con traje sastre, los meñiques levantados mientras tomamos té. Sino escribir nuestros programas fáciles de entender, bien documentados y siguiendo convenciones de escritura previamente adoptadas. Esto hará que nuestro código sea universal. 15 | 16 | Sí, cada programador es único y tiene su manera de hacer las cosas, sin embargo esto se puede convertir en un gran problema cuando se tenga que optimizar, corregir o ampliar el código de una aplicación. En el mejor de los casos recordarás para qué sirve esa variable llamada **asdflkj** que escribiste hace meses… en el peor de los casos no serás tu quién tenga que hacerlo. 17 | 18 | O tal vez esa sea tu intención: "si fue dificil de escribir, que sea difícil de entender". Pero esperemos que no. 19 | 20 | ## Parte del problema 21 | 22 | En mi opinión, parte del problema viene desde las escuelas tradicionales, al menos en la que yo estudié, cada semestre eran proyectos nuevos para cada asignatura, entonces ni te preocupabas por tener que hacer las cosas mantenibles, con que el "sistema" funcionara al final del semestre bastaba. 23 | 24 | Creo que no se nos inculca la habilidad de trabajar sobre una sola cosa y darle mantenimiento con el tiempo, lo cual nos forzaría (o al menos nos indicaría que) debemos hacer las cosas bien desde el inicio. Para mi fue una gran sorpresa el día que en el trabajo tuve que regresar a modificar el código que había escrito apenas unos meses atrás. Como una película de terror. 25 | 26 | ## Una posible solución 27 | 28 | Como uno de los esfuerzos por combatir estas malas prácticas en cuanto a la escritura del código es que surgieron las **guías de estilo**, que no son mas que especie de "reglas" para nombrar nuestras variables, métodos o funciones, clases… y hasta algunas de las más celebres batallas como usar tabs o espacios o poner el corchete de apertura en la misma línea o no. 29 | 30 | No existe una única guía de estilo para cada lenguaje, sino que pueden existir varias, dependiendo del proyecto o la organización que las adopte. Por ejemplo, existen las *Coding conventions* de C# que son recomendadas por Microsoft para el lenguaje, luego también existe la guía de estilo de la fundación .NET, pero también existen las Coding guidelines para el proyecto MonoGame. 31 | 32 | Seguramente para el lenguaje de tu preferencia o con el que estés trabajando actualmente también existen estas guías de estilo. Y si no existe o sientes que ninguna se adecua a tus necesidades (o las de tu organización), no te preocupes: si bien lo más recomendable es que sigas alguna guía existente, desarrollar la tuya propia y aplicarla en el código. 33 | 34 | Ya sea que encuentres una guía o crees una propia, el paso siguiente **aplicarla consistentemente**, de nada servirá si usas una un día y al otro la cambias. El uso de las guías de estilo es una de las cosas que hacen más sencilla la colaboración en el código, además de los sistemas de control de versiones. 35 | 36 | Y ahora comienzen a programar con estilo si es que aún no lo hacen. Nos vemos la próxima. -------------------------------------------------------------------------------- /content/posts/2015-08-21-string-vs-system-string-es.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Un post sobre alias, ¿string vs. System.String? 4 | date: 2015-08-21 13:00:00 5 | author: Antonio Feregrino 6 | categories: c-sharp 7 | summary: He de aceptarlo, una de las cosas que más dudas me causaba cuando inicié a programar usando C# era sobre cuál era la diferencia entre usar string o System.String, la idea que yo tenía al respecto que estaba totalmente equivocada. 8 | lang: es 9 | featured_image: featured.jpg 10 | alias: /string-vs-system-string-es/index.html 11 | tags: AprendeCSharp 12 | featured_tag: AprendeCSharp 13 | --- 14 | 15 | He de aceptarlo, una de las cosas que más dudas me causaba cuando inicié a programar usando C# era sobre cuál era la diferencia entre usar string o System.String, la idea que yo tenía al respecto que estaba totalmente equivocada. Tenía la mala creencia de que `string` y `String` (sí, la diferencia es la mayúscula inicial) eran cosas un tanto distintas cuando resulta que no es así. 16 | 17 | ### Alias 18 | Resulta que `string` y `System.String` (o simplemente `String`) son lo mismo, es decir, en nuestro código podemos fácilmente intercambiar ambas palabras sin problema alguno. Por poner otro ejemplo, usando el alias para `Int32`, podemos escribir de cualquiera de las dos siguientes maneras y el código significará lo mismo. 19 |
20 |
21 | ```csharp 22 | int abc = 123; 23 | Int32 xyz = 123; 24 | ``` 25 |
26 |
27 | ```csharp 28 | Int32 abc = 123; 29 | int xyz = 123; 30 | ``` 31 |
32 |
33 | 34 | #### ¿Referencias o valores? 35 | Como parte de mis falsas creencias, pensaba que al usar `System.Int32` estaba creando tipos de dato por referencias (o *envoltorios*, como en Java) con todo lo que eso representa, pero repito: No es así. Todos los tipos de valor permanecen así independientemente de cómo los hayamos declarado. Eso sí, no olvides que `string` y por tanto `String` son un tipo de referencia. Abajo pongo una tabla con algunos alias de C#: 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
AliasFrameworkTipo
intSystem.Int32Valor
boolSystem.BooleanValor
floatSystem.SingleReferencia
objectSystem.ObjectReferencia
65 | 66 | 67 | #### ¿Para qué existen? 68 | Puede que te estés preguntando eso, y la verdad es que no sé. Muchos sugieren que es por cuestión de hábito, ya que los alias se parecen (si no es que son iguales) a las declaraciones de variables para lenguajes de programación más antiguos que C#, como C o C++. Para un programador sería más sencillo migrar de un lenguaje a otro si encuentra cosas parecidas a las que está acostumbrado, aunque sean detalles pequeños como este. 69 | 70 | #### ¿Cuál es correcto? 71 | Al significar lo mismo en términos de programación su uso es cuestión de gustos, pero yo prefiero usar el alias para declarar variables, tipos de dato de retorno y parámetros de método. Mientras que prefiero usar el nombre "completo" para hacer referencia a métodos y constantes de cada tipo, por ejemplo 72 |
73 |
74 | ```csharp 75 | // Yo prefiero... 76 | int abc = Int32.Parse("123"); 77 | string emptyString = String.Empty; 78 | ``` 79 |
80 |
81 | ```csharp 82 | // ... a esto 83 | Int32 abc = int.Parse("123"); 84 | String xyz = string.Empty; 85 | ``` 86 |
87 |
88 | 89 | #### Lo que sigue 90 | En el siguiente post les platicaré de una forma en la que podemos crear nuestros propios alias y así también tomar ventaja de las características que nos ofrece el lenguaje. 91 | -------------------------------------------------------------------------------- /content/posts/tv/2017-07-25-package-manager.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Gestores de paquetes 3 | slug: package-manager 4 | date: 2017-07-25 18:00:00 5 | youtube_id: tiifSYUCwQA 6 | images_folder: /tv/package/ 7 | summary: Los gestores de paquete le otorgan a los desarrolladores una manera más sencilla de reutilizar el código creado por otros, al manejar la instalación, actualización y remoción de bibliotecas de software. 8 | featured_image: package.jpg 9 | tags: Meta, YouTube 10 | featured_tag: Tv 11 | layout: video 12 | post-routes: 13 | - /post/{}/index.html 14 | - /tv/{}/index.html 15 | - /post/{}.html 16 | --- 17 | 18 | Los gestores de paquetes son esas herramientas sin las cuales el desarrollo actual sería un gran dolor de cabeza. Y es que últimamente son el pan de cada día de los desarrolladores, especialmente si se está trabajando con tecnologías "modernas" como el desarrollo móvil o web. 19 | 20 | Estos no nacieron inicialmente como una herramienta netamente enfocada al desarrollo de software, sino como una herramienta para añadirle funcionalidad a los sistemas operativos basados en Linux, si has usado alguna distro de Linux tal vez te suene familiar las palabras "apt", o "yum", pues bien, esos son gestores de paquetes. 21 | 22 | Esta idea después migró al código, otorgándole a los desarrolladores una manera más sencilla de reutilizar el código creado por otros al manejar la instalación, actualización y remoción de bibliotecas de software, de hecho desde 1995 en que CPAN (un archivo de módulos para el lenguaje PERL) fue puesto en línea, es que se tiene la primera noción de un gestor de paquetes para el desarrollo. 23 | 24 | Los gestores de paquetes tienen muchos beneficios, pero dos de los que hay que destacar son los siguientes: 25 | 26 | - Los gestores de paquetes reducen la cantidad de código de la que tienes que hacerte cargo: bueno, esto es solo una consecuencia de usar código de terceros, sin embargo, los gestores de paquetes suelen encargarse de más tareas que las de simplemente descargar una pieza de software, hay algunos que inclusive la integran a tu código añadiendo archivos auxiliares o inclusive modificando la configuración de tu proyecto. 27 | 28 | - Hacen más sencilla la tarea de añadir y gestionar las bibliotecas a tu proyecto, y es que tú ya no estás a cargo de instalar las bibliotecas. Encima de todo se encargan también resolver otras dependencias que estas bibliotecas que estás instalando tengan, así podría parecer que tu instalas solo un paquete, cuando en realidad el gestor está instalando otros tres sin que tú te tengas que preocupar por ellos. A esto se le llama gestión de dependencias. 29 | 30 | - Además, muchos de ellos son compatibles con el versionamiento semátnico, que como ya vimos en un video pasado, tiene muchas ventajas a la hora de desarrollar bibliotecas que cuentan con una API. 31 | 32 | En la actualidad es muy sencillo para todos crear una biblioteca de código y hacerla disponible a todo el mundo a través de los gestores de paquetes. Bastaría con que empaquetaras tu código de una forma en la que el gestor la entienda y lo pongas en un lugar accesible como un servidor en internet, de hecho, muchos de los gestores de paquetes ofrecen servicio de alojamiento para que los desarrolladores coloquen ahí lo que desarrollen. 33 | 34 | Pero no te preocupes, que usar un gestor de paquetes no es obligatorio, puesto que siempre tendrás la opción de descargar la biblioteca que deseas usar y compilarla tu mismo (si es posible) y luego instalarla a mano en tu proyecto, aunque esto no suene tan atractivo después de hacerlo varias veces. 35 | 36 | Para tu lenguaje o entorno seguramente existen los gestores de paquetes, con el que yo estoy más familiarizado es con NuGet o *Nu-jeh* como dice Miguel de Icaza, aunque también existe Packet, si lo tuyo es Xcode ahí tienes CocoaPods, Composer si rabajas con PCP, gopm para GO, en fin, en este enlace podrás encontrar muchos más gestores de paquetes. -------------------------------------------------------------------------------- /content/posts/tv/2017-12-11-expresiones-lambda.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Las expresiones lambda 3 | date: 2017-12-18 18:00:00 4 | youtube_id: DvE-J-jgB_A 5 | images_folder: /tv/lambdas/ 6 | summary: Las expresiones lambda son bloques de código que NO están asociados con un identificador. 7 | featured_image: featured.png 8 | tweet_id: 942879414903300096 9 | tags: Meta, YouTube 10 | featured_tag: Tv 11 | layout: video 12 | --- 13 | 14 | Las expresiones lambda o funciones lambda, o, por su nombre correcto: las funciones anónimas son bloques de código que NO están asociados con un identificador... es decir, en tiempo de ejecución no tienen un nombre asociado. Como por ejemplo estas que son funciones (o métodos) pero si tienen un nombre: 15 | 16 | _ejemplos_ 17 | 18 | Como puedes ver, todos estos ejemplos las funciones están asociados fuertemente con un nombre. Mientras que en el caso de las expresiones lambda esto no es necesario. Estos son ejemplos de expresiones lambda que definen lo mismo que los métodos anteriores. 19 | 20 | _ejemplos_ 21 | 22 | ## Sintaxis 23 | 24 | Para definirlas la sintaxis varía de lenguaje a lenguaje, sin embargo generalmente la sintaxis es algo como esto: 25 | 26 | ``` 27 | Argumentos - Operador - (Contenido)Expresión 28 | ``` 29 | 30 | ### C# 31 | En C# se define de la siguiente manera: 32 | 33 | ``` 34 | (int x) => { return x*x; }; 35 | ``` 36 | 37 | ``` 38 | (int x) => 39 | { 40 | var x_squared = x*x; 41 | return x_squared; 42 | }; 43 | ``` 44 | 45 | En C# podemos no usar los paréntesis siempre y cuando se trate de una expresión lambda de 1 solo argumento... ah, y podemos quitar los corchetes, y la palabra `return` siempre y cuando el contenido de la lambda sea una sola expresión. 46 | 47 | ``` 48 | x => x*x; 49 | ``` 50 | 51 | ### Python 52 | 53 | Usando Python la cosa cambia un poco, pero verás que la estructura sigue siendo la misma, tenemos algo así: 54 | 55 | ``` 56 | lambda x: x*x; 57 | ``` 58 | 59 | En Python no hay nada más que hacer, no hay que usar paréntesis para especificar multiples argumentos, basta con separarlos con una coma. Sin embargo existe una desventaja: las lambdas en este lenguaje solamente deben contener una expresión. 60 | 61 | ### JavaScript 62 | 63 | JavaScript es muy similar a C#: 64 | 65 | ``` 66 | exp1 = (x) => { return x*x; }; 67 | ``` 68 | 69 | ``` 70 | exp4 = x => 71 | { 72 | x_squared = x*x; 73 | return x_squared; 74 | }; 75 | ``` 76 | 77 | En el sentido de que se puede reducir la expresión lambda siempre y cuando el cuerpo de la expresión lambda sea... una sola expresión. 78 | 79 | ``` 80 | exp3 = x => x*x; 81 | ``` 82 | 83 | Existen también en Java (aunque ahí son un poco raras), en Go, Haskell, C++, PHP... y en muchos más. 84 | 85 | ## Razón de ser 86 | 87 | Pero, ¿para qué querríamos escribir este tipo de expresiones? Las expresiones lambda nos ayudan a 88 | 89 | - Evitarnos el escribir código innecesario, y a la vez evitarnos llenar nuestro código de lógica que solamente vamos a usar una sola vez o en una sola parte del código. Si, por ejemplo, necesitas ejecutar una operación sobre un conjunto de elementos, tal vez sea mejor usar una expresión lambda que crear un método o una función que nadie más va a usar. 90 | 91 | - Reducir la complejidad de nuestro código al evitarnos tener que navegar entre lineas para llegar a la definición de una función. La lectura del código se hace más sencilla, puesto que la definición del método está más a la vista de quien la está usando y no tiene que andar navegando entre todo el laberinto de código. 92 | 93 | - Nos ayudan a crear funcionalidad que luego puede ser pasada como argumentos a otras funciones, llamadas funciones de orden superior. Esto no es una cosa exclusiva de este tipo de expresiones, pero sin duda lo hace más sencillo. 94 | 95 | Como podrás imaginarte, las funciones anónimas están relacionadas muy fuertemente con la programación funcional, de la cual ya les hablé en el pasado, sin embargo no es el único paradigma de programación en el que se le puede encontrar. -------------------------------------------------------------------------------- /content/posts/2015-12-16-ser-xamarin-student-partner.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Ser un Xamarin Student Partner 4 | date: 2015-12-16 18:31:38 5 | author: Antonio Feregrino 6 | categories: blog es 7 | summary: Que yo les hable tanto de Xamarin en este blog no es obra de la casualidad, y es que formo parte de los primeros Xamarin Student Partners, un grupo formado a principios de 2015 formado por estudiantes interesadoes en difundir el desarrollo móvil. 8 | featured_image: featured.png 9 | lang: es 10 | tweet_id: 677330366580002816 11 | tags: Meta 12 | featured_tag: Meta 13 | --- 14 | 15 | Que yo les hable tanto de Xamarin en este blog no es obra de la casualidad, y es que formo parte de los primeros *Xamarin Student Partners*, un grupo formado a principios de 2015 al que pertenecen estudiantes interesados en difundir el desarrollo móvil multiplataforma en varias universidades al rededor del mundo. En este post, te cuento de mi experiencia hasta ahora. 16 | 17 | Sin duda, si 18 | 19 | - Te gusta hacer aplicaciones en tu tiempo libre 20 | - Tienes habilidades para comunicarte 21 | - Publicas y contribuyes a código en GitHub 22 | - Te gusta (o estás interesado) el desarrollo en C# 23 | - Te gusta enseñar a otros 24 | - (**Plus**) Tienes experiencia desarrollando para Android o iOS 25 | 26 | Disfrutaras todo del programa que Xamarin ofrece para estudiantes. 27 | 28 | Por poner un ejemplo: A mi me encanta eso de enseñar (y aprender) de otros, y pertenecer a este grupo me provee de los recursos suficientes para hacerlo. Y cuando hablo de recursos no estoy diciéndolo a la ligera: Comenzando con una **licencia tipo *Business*** que nos permite hacer y deshacer cuanto queramos en cuanto a cosas de Xamarin se refiere (incluyendo vender nuestras aplicaciones en las tiendas de apps). 29 | 30 | Pero, **¿para qué querríamos una licencia si no sabemos qué hacer con ella?** Pues no te preocupes, porque además de la licencia, también tenemos acceso gratuito a la Xamarin University que bien le hace honor a su nombre puesto que es un lugar en donde puedes aprender a desarrollar aplicaciones con Xamarin.iOS, Xamarin.Android y con Xamarin.Forms. Pero la cosa no se queda ahí, además hay clases sobre testing, telemetría, C# y F#. 31 | 32 | La cosa no se queda ahí, una vez que ya aprendiste todo lo que querías sobre la tecnología, también tienes la posibilidad de **certificarte como *Xamarin Certified Developer***, la cual es una certificación totalmente válida y avalada por la compañía misma. Todo gratis para nosotros. 33 | 34 | Y bueno, **estoy aprendiendo, pero también quiero enseñar**. Genial, de eso se trata. Tienes el apoyo de la empresa tanto con recursos materiales con cosas para regalar (monitos, estampas, playeras...) entre los asistentes a tus pláticas y talleres, además de materiales digitales (diapositivas, código, documentación...) para prepararlos y llevarlos a cabo. 35 | 36 | Además de aprender y enseñar, es importante **compartir experiencias con otros *student partners* alrededor del mundo** y esto se puede hacer gracias a la comunidad de Slack en donde estamos todos concentrados para platicar, hacer equipos y desarollar ideas. Y ni hablar de la posibilidad de asistir a eventos locales de Xamarin para compartir con aún más personas. 37 | 38 | Todo esto y más (no hablé de las horas de *Test Cloud*) a cambio de hacer lo que te gusta: aprender y **enseñar** de una tecnología que te gusta. Honestamente no creo que exista un programa tan bueno para los estudiantes como este. 39 | 40 | Si estás interesado pero no cumples con los requisitos, no te preocupes, algunas de esas son cosas que se pueden aprender sobre la marcha, y te resultará sencillo si en verdad te interesa, por lo pronto el registro está abierto para la nueva generación de XSP que comenzará a principios de 2016. Si quieres algún consejo o tienes alguna duda no dudes en contactarme, a pesar de que soy solo un miembro más del programa, espero poder orientarte un poco. -------------------------------------------------------------------------------- /content/posts/2017-01-02-metas-blog-2017.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Metas de That C# guy en 2017 4 | date: 2017-01-02 18:31:38 5 | author: Antonio Feregrino 6 | categories: blog 7 | summary: Nuevo año, nuevas metas para That C# guy, conócleas. 8 | images_folder: /meta/ 9 | featured_image: 2017.png 10 | tags: Meta 11 | featured_tag: Meta 12 | --- 13 | 14 | Antes de comenzar: 15 | 16 | > Te deseo a ti, que estás leyendo esto, un feliz y próspero año nuevo 17 | 18 | Este es un post muy distinto a la temática en general que manejo en este blog, y es que, con motivo del inicio de este nuevo año, me tomé un momento para reflexionar y pensar sobre la dirección que le voy a dar a este sitio y quería compartir las conclusiones (en forma de objetivos) a los que llegué con respecto al blog. 19 | 20 | ## Publicar aplicaciones 21 | Por mi cuenta he algunas aplicaciones tanto en la tienda de Windows como en la de Android, sin embargo, la mayoría no son... dignas de ser presumidas como me gustaría. Es por eso que a lo largo de este año tengo el firme propósito de crear una o varias aplicaciones completas y totalmente funcionales, usando los conocimientos que ya poseo y añadiéndole los que vaya aprendiendo. 22 | 23 | Desde luego y como ha sido hasta este momento, iré publicando en este blog consejos, tips y experiencias con las que me encuentre mientras desarrollo dichas aplicaciones. 24 | 25 | ## Este blog 26 | Mantendré el firme compromiso de publicar un artículo cuando menos una vez a la semana, esta vez trataré de establecer un calendario editorial que haga que exista cierta continuidad entre algunos temas relacionados. 27 | 28 | También me gustaría retomar los post del tipo: "¿Qué puedo hacer con C#?" o "NuGet recomendado". Pero para esto me gustaría pedirles su participación en una "pequeña" encuesta, la cual me ayudará a darme una idea sobre los temas que les interesan. Si pueden y quieren participar, aquí dejo el enlace: 29 | 30 | 31 | 32 | 33 | 34 | ### En inglés 35 | También me gustaría publicar un poco más en inglés, y no solo por gusto, sino que en verdad es una herramienta necesaria para quien se dedica a desarrollar aplicaciones. Procuraré publicar los posts más importantes en los dos idiomas, aunque no siempre sea posible publicar ambos al mismo tiempo. 36 | 37 | ## YouTube 38 | Confío en que este año sea mejor para el canal de YouTube, publicando al menos una vez cada quince días, alternando entre un tema teórico y uno práctico, retomando así lo que al inicio del canal plantee como sus objetivos. Buscaré también la posibilidad de crear una serie de videos sobre cómo utilizar las tecnologías de las que hablo en este blog, enfocados totalmente en la práctica. 39 | 40 | Si aún no estás suscrito al canal, te invito a que lo veas y si te gusta, suscribirte: 41 | 42 | 43 | 44 |
45 | 46 | ## Tu 47 | Sí, tu. Tu eres parte importantísima de este blog, es por eso que me gustaría saber si existe algo en particular que te gustaría ver en este sitio: desde una sección de preguntas y respuestas, una serie de posts o alguna explicación sobre algún tema que te cueste entender. 48 | 49 | De verdad me interesa conocer tu opinión, recuerda que me la puedes hacer llegar todas tus dudas, quejas y comentarios por las vías usuales: Twitter, Email y Facebook. 50 | 51 | Y de nuevo, si puedes y quieres contestar la encuesta: muchas gracias. 52 | -------------------------------------------------------------------------------- /content/posts/2016-06-02-meetup-1-junio-2016.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Primer Meetup Xamarin Students México 4 | date: 2016-06-03 22:00:00 5 | author: Antonio Feregrino 6 | summary: Parte de las presentaciones que hubo en el Meetup Xamarin Students México del 1 de junio de 2016 en Urban Station. Una demo de Custom Renderers. 7 | lang: es 8 | featured_image: 1-jun-2016.jpg 9 | images_folder: events/ 10 | tags: Xamarin, XamarinForms, Events 11 | featured_tag: Xamarin 12 | --- 13 | 14 |
15 | 16 |
17 | 18 |
19 | Esta es la presentación y el código la charla que di sobre *custom renderers* en el Meetup de Xamarin Students México junto a Humberto quién habló de estrategias para compartir código y Vicente quién habló de las diferencias entre Forms y Xamarin tradicional. 20 | 21 | Puedes checar el [código fuente del demo](https://github.com/fferegrino/custom-renderers-talk/releases/tag/m-1) en GitHub. 22 | 23 | ## Diapositiva 9 - Renderers de Xamarin.Forms 24 | El código fuente de Xamarin.Forms (y otras de sus tecnologías relacionadas) es ahora *open source* y puedes checarlo también en GitHub: [https://github.com/xamarin/Xamarin.Forms](https://github.com/xamarin/Xamarin.Forms). Podemos ayudarnos de esto para ver cómo es que están hechos sus *renderers*: 25 | 26 | Button y sus implementaciones: 27 | 28 | Abstracción de Button 29 | Renderer en iOS 30 | Renderer en Android 31 | Renderer en Windows 32 | 33 | ## Diapositiva 10 - Aplicación demo 34 | 35 | El cliente de la Pokéapi es Jirapi, hecho por mi, puedes leer más sobre él aquí. 36 | 37 | ## Diapositiva 12 - Effects 38 | Para modificaciones simples, puedes usar una de las funciones más nuevas de Forms, los Effects. 39 | 40 | 41 | ## Diapositiva 15 - Ejemplos "reales" 42 | Estos son ejemplos de proyectos y productos que usan *custom renderers* para funcionar: 43 | 44 | - Xlabs: https://github.com/XLabs/Xamarin-Forms-Labs 45 | - Telerik UI for Xamarin: http://www.telerik.com/xamarin-ui 46 | - Messier16 Controls: https://github.com/messier16/Forms.Controls 47 | 48 | ## Siguiente evento 49 | Si quieres estar al tanto de los siguientes eventos, no olvides darle *me gusta* a nuestra página de Facebook o unirte al grupo en Meetup. 50 | 51 | Muchas gracias a Urban Station por patrocinar el lugar para el evento. -------------------------------------------------------------------------------- /templates/includes/sidebar/article-menu.html: -------------------------------------------------------------------------------- 1 | 8 | 9 |
10 |
TOC
11 |
12 |
13 | 14 | 123 | -------------------------------------------------------------------------------- /content/posts/2015-08-15-importance-of-coding-with-style.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: The importance of coding with style 4 | date: 2015-08-15 17:00:00 5 | author: Antonio Feregrino 6 | lang: en 7 | categories: ['programming', 'professional development', 'en'] 8 | summary: And with "coding with style" I don't mean to keep your pinkies up while doing it or just write code every evening at 5:00 pm. No. 9 | github: https://github.com/fferegrino/cool-sharp#eng 10 | featured_image: featured.jpg 11 | alias: /importance-of-coding-with-style/index.html 12 | tags: Meta 13 | featured_tag: Meta 14 | --- 15 | 16 | And with "coding with style" I don't mean to keep your pinkies up while doing it or just write code every evening at 5:00 pm. No. Coding with style is to make our code legible, documented as much as we can an following some conventions that other coders adopt to make our programs "universal". 17 |
18 | They say that every programmer has its own way to do its thing (I agree on that), but this sometimes becomes a problem when it comes to terms of optimization, review or scale the code. In the best of cases we might remember everything what that *asdflkj* variable means in our code, but imagine if you couldn't remember and you have to look here and there to find what you meant to do with that variable. OR EVEN WORSE: Imagine that the code you wrote a long time ago is now a responsibility for other person, poor him! 19 |
20 | "It works", yeah, you could say that. There are times when a quick fix is needed but at the end of the day we always forget to come back and do it right. But trust me, that will make the life easier for you and your colleagues. 21 | 22 | ### One of the problem's sources 23 | I believe the problem comes right from our schools (at least mexican schools), where when we are asked to present our homework, projects or practices we settle for "well, it works" because we never work over the same thing again. Every teacher ask for new things, not the ones we have worked previously on with other teachers. It would be ideal if at the very beginning we could choose a long term project to force ourselves to constantly improve it and to make things right. 24 |
25 | It'll help if we decide to get into the working world where over time the same application is developed, and to make that development easy the code must be well documented making it easy to be worked on by a lot of hands and without wasting time by asking our partner "what does this do?" or scratching our heads wondering for what did we used some variable instead of another. 26 | 27 | ### A brilliant solution 28 | Luckily for us there are some style guides that give us some conventions, which we may not take as if they were laws but I recommend that you take them in account. Of course, you can create your own styles of coding, the important part of adopting or creating a style is to **apply it as consistently as we can**. 29 |
30 | My fellow programmer, below are some links to style guides that I found somewhere (in the internet), if your language isn't listed there, keep looking or create your own. Speaking of that... **I decided to write my very own style guide for C#**, it is on GitHub and everyone can contribute to its development. 31 |
32 | 33 | #### [Yet another *cool* style guide for C#](https://github.com/fferegrino/cool-sharp/) 34 | Otras guías: [C++](https://sites.google.com/site/fferegrinostorage/-getguiasdeestilo/estilosCPlusPlus1.htm?attredirects=0&d=1), [C++](https://sites.google.com/site/fferegrinostorage/-getguiasdeestilo/estilosCPlusPlus2.pdf?attredirects=0&d=1), [C#](https://sites.google.com/site/fferegrinostorage/-getguiasdeestilo/estilosCsharp1.pdf?attredirects=0&d=1), [C#](https://sites.google.com/site/fferegrinostorage/-getguiasdeestilo/estilosCsharp2.pdf?attredirects=0&d=1), [Java](https://sites.google.com/site/fferegrinostorage/-getguiasdeestilo/estilosJava1.pdf?attredirects=0&d=1), [Java](https://sites.google.com/site/fferegrinostorage/-getguiasdeestilo/estilosJava.pdf?attredirects=0&d=1), [PHP](https://sites.google.com/site/fferegrinostorage/-getguiasdeestilo/estilosPHP1.htm?attredirects=0&d=1), [PHP](https://sites.google.com/site/fferegrinostorage/-getguiasdeestilo/estilosPHP.htm?attredirects=0&d=1). 35 | -------------------------------------------------------------------------------- /content/posts/tv/2018-06-12-big-data.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Big Data 3 | date: 2018-06-12 18:00:00 4 | youtube_id: bQ-2mZoWLGE 5 | categories: big-data 6 | summary: This is going to be a short video since what we mostly did was trying to understand the motivation and design decisions behind all these systems. I'll put the links to all the papers we reviewed so you can take a look at them. 7 | lang: en 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | # Big Data 14 | We took a look at some of the foundations of big data systems (some of them are even outdated now), from a more academic point of view. 15 | 16 | This is going to be a short video since what we mostly did was trying to understand the motivation and design decisions behind all these systems. I'll put the links to all the papers we reviewed so you can take a look at them. 17 | 18 | Starting with... 19 | 20 | ## Google File System 21 | This was the first distributed file system Google created to store all the information they manage; it has since then been replaced by Colossus. However, the foundations remain. 22 | 23 | From there we jumped to ... 24 | 25 | ## (HDFS) or Hadoop File System 26 | Which is again, a distributed file system, in this case, inspired by GFS. As I mentioned earlier, we start with the foundations, that is Version 1 version of HDFS only to see the differences with the second version (and now there is a third version out, yey!). 27 | 28 | Once we learned a bit about HDFS, we learned about his companion, the programming model called... 29 | 30 | ## MapReduce 31 | Which is a useful technique to process vast amounts of information in a distributed way, taking advantage of having lots of relatively cheap computers. I made a whole video dedicated to MapReduce; you can check the link in the description. 32 | 33 | However, MapReduce is somewhat outdated too, and it has some limitations. We reviewed other more modern approaches to work with Big Data problems using... 34 | 35 | ## Spark 36 | Which is a framework for distributed computing that allows us to specify transformations over a dataset without actually doing them right away but in a lazy manner. Spark has its foundation on the concept of Resilient Distributed Datasets: read-only collections of data distributed over nodes in a cluster. I'll probably make a video about Spark in the future. 37 | 38 | Both MapReduce and Spark run on top of a distributed filesystem, benefitting themselves from the characteristics of such systems. 39 | 40 | After learning about these two processing approaches, we went on to learn about more different ways of storing information using distributed NoSQL Data Stores like... 41 | 42 | ## Bigtable 43 | Another one of those Google creations, in the first line of the paper it says what Bigtable actually is: Bigtable is a distributed storage system for managing structured data that is designed to scale to a huge size. And that's about it, I mean, is way more complex that I'm making it sound here, but I won't go into details. 44 | 45 | Again we briefly saw an open source version of Bigtable called **HBase**. 46 | 47 | ## Cassandra 48 | Finally, we reviewed Cassandra, another highly distributed data store, and its approach to decentralise the knowledge that the other approaches had centralised in a master node, another interesting thing is its ease to work across data centres. 49 | 50 | As for the practical side of things we did a couple of exercises: one using MapReduce and the other one using Spark on a school provided cluster. Both exercises involved calculating PageRank scores of some Wikipedia articles. 51 | 52 | As you can probably guess all of these systems involve a coordination hell as all of them are distributed and hold redundant copies of data some of them not only on a single cluster but across the entire world. 53 | 54 | And that was it, as I said for all of those systems we reviewed their main components such as Master nodes or DataNodes or whatever they were called on each of the implementations and the basic techniques that powered their reliability like writing to logs or creating checkpoints, along with some of the tools that helped these tools achieve great performance like LSMTrees, SSTables and Bloom filters. 55 | 56 | -------------------------------------------------------------------------------- /content/posts/2015-12-09-c-sharp-juegos.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Cosas para hacer en C#: Juegos" 4 | date: 2015-12-09 21:00:00 5 | author: Antonio Feregrino 6 | categories: c-sharp 7 | summary: C# no es solo trabajo de oficina de 9 a 5, también se pueden hacer algunas otras cosas bastante divertidas pero sobre todo interesantes, como videojuegos. 8 | featured_image: featured.jpg 9 | lang: es 10 | tweet_id: 674778550726172673 11 | tags: AprendeCSharp 12 | featured_tag: AprendeCSharp 13 | --- 14 | 15 | Por el título de este post ya se podrán imaginar qué viene a continuación. Como saben este blog se enfoca principalmente en enseñar e inspirar a quién lo lee a programar en C#, pero muchas veces nos quedamos con esa sensación de ¿Y luego, qué? 16 | 17 | Me he encontrado con que uno de los motivos que evita que la gente quiera apender C# es que aún existe la creencia de que los lenguajes de .NET son solo para el desarrollo de aplicaciones empresariales y que para poder vivir de programar en C# deberán encontrar un trabajo de 9 a 5 en alguna corporación maligna. 18 | 19 | Pero no, resulta que se pueden hacer un montón de cosas, incluyéndo videojuegos. Para hacer juegos, tenemos dos opciones: 20 | 21 | ### C# desde "cero" 22 | Gracias a la comunidad de Mono y a MonoGame, se han hecho grandes avances en el desarrollo de videojuegos con .NET. Permiten alcanzar una calidad en el juego al grado que ya se han publicado varios videojeugos para PC exitosos escritos en C#, por ejemplo: FEZ y Bastion. 23 | 24 | Pero, ¿cuál es el chiste?, te preguntarás, si C# siempre ha funcionado en Windows. Pues resulta que estos juegos también han brincado las fronteras de la PC y ahora hay algunos para Play Station 4 (¡y Apple TV!): Por si no sabías, Transistor y TowerFall también están hechos en el fabuloso C#. 25 | 26 | ### Utilizando un motor 27 | Si vas comenzando con la creación de videojuegos, tal vez crear uno desde cero no sea la mejor opción. Para ello existen algunas herramientas conocidas como *motores de juego* que te ayudan quitando muchas de las complicaciones técnicas de crear un juego dejándote a ti la tarea de dedicarte a programar la lógica de tus creaciones. Una vez que tu juego está terminado estos motores lo compilan y dejan un producto que puede ser exportado a múltipes plataformas. 28 | 29 | Los dos motores que conozco, y he probado, son Unity 3D y Unreal Engine, ambos soportan C# como lenguaje de *scripting*, es decir, para definir el comportamiento de los elementos de nuestro juego. Hay muchos ejemplos de juegos que se pueden hacer con ellos, inclusive Rovio (sí, el creador de Angry Birds) usó Unity para crear su juego **Bad Piggies**. 30 | 31 | En esta parte, en lugar de dar ejemplos, les dejo algunos enlaces a tutoriales bastante buenos en los que me basé para hacer Woha!, un jueguillo para Android en el que usé C#. 32 |
33 |
34 | 35 |
36 |
37 | Entren al canal de YouTube de Hagamos Videojuegos en él encontraran como hacer shooters, runners e inclusive aprender un poco sobre realidad aumentada. 38 | 39 | #### Para terminar 40 | Como puden ver, C# no es solo trabajo de oficina de 9 a 5, también se pueden hacer algunas otras cosas bastante divertidas pero sobre todo interesantes. En un futuro hablaré sobre qué más se puede programar con él, ¿tienes alguna idea? cuéntame vía correo o Twitter ;). -------------------------------------------------------------------------------- /content/posts/tv/2017-12-18-jupyter-notebooks.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Los Jupyter Notebooks 3 | date: 2017-12-11 18:00:00 4 | youtube_id: xcXky3PxVHA 5 | images_folder: /tv/jupyter/ 6 | summary: Los Jupyter Notebooks son una herramienta bastate útil para documentar el código antes de llevarlo a producción. ¡Y no son solo para Python! 7 | featured_image: featured.png 8 | tweet_id: 940237219826229248 9 | lang: en 10 | tags: Data science, Meta, YouTube 11 | featured_tag: Tv 12 | layout: video 13 | --- 14 | 15 | Los Notebooks de Jupyter son unas hojas de código interactivas... 16 | 17 | El código ya es interactivo por si mismo, puedes modificarlo, ejecutarlo a tu antojo... pero el tipo de interactividad que ofrecen los Jupyter Notebooks es algo distinto, pero vamos a ver algo de historia... 18 | 19 | La idea detrás de estos Notebooks proviene de IPython que es un proyecto orientado a ofrecer una consola interactiva para trabajar con el lenguaje de programación Python (este proyecto fue iniciado por Fernando Pérez, un físico desarrollador de software colombiano), el proyecto, que ya era de por si interesante, tuvo una adición importantísima en 2011 con la aparición de los IPython Notebooks (ahora llamados Jupyter Notebooks) para convertirse en un entorno con el cual podemos interactuar a través de un navegador. Básicamente la idea era ofrecer un entorno para facilitar la tarea de la programación orientada al ámbito científico, sin embargo, también tiene un uso genérico con gran potencial. Espero veas por qué con esta rápida introducción. 20 | 21 | Permite trabajar con gráficas, ecuaciones, videos, imágenes, simuladores y desde luego, código. Todo... combinado. Imagina: combinar las características de un entorno simple de programación (como el *syntax highlighting* y auto-completado) con la habilidad de poder escribir texto enriquecido junto al código. La idea es que sirva para documentar lo más posible alguna tarea que estamos realizando, tan solo para después tomar solo el código y llevarlo a una aplicación productiva. Además ofrece posibilidades para que cada uno de estos Notebooks sea evaluado automáticamente, lo cual también los hace ideales para hacer prácticas escolares, y de hecho, en la universidad ya he tenido ya varias prácticas así. 22 | 23 | Los Notebooks se crean con la Notebook App, que es una aplicación que está compuesta por dos componentes en una arquitectura cliente-servidor. 24 | 25 | La parte del cliente es el editor de código con el cual creamos y modificamos los Notebooks; este editor basado en HTML, CSS y JavaScript es el que usamos a través de un navegador web, aquí es donde escribimos el código y vemos los resultados de ejecutarlo. 26 | 27 | Mientras que el servidor se encarga de ejecutar el código que nosotros introducimos en los Notebooks y devolver los resultados al cliente. Este servidor es una especie de servidor web que a cada una de estas hojas interactivas les asigna un hilo de ejecución dentro de la computadora en la que está corriendo, y es en realidad dentro de este hilo de ejecución en donde se ejecuta nuestro código. El cliente y el servidor se comunican a través de peticiones HTTP y WebSockets. 28 | 29 | Al ser de código abierto (y al tener una gran comunidad detrás) tiene muchas posibilidades de ser expandido mediante Widgets que los dotan de mayor funcionalidad. Entre estos Widgets están algunos que permiten trabajar con información geoespacial, video y audio, crear tablas paginadas o crear una "interfaz amigable" para modificar el código. Y es también gracias a la comunidad que soporta diversos lenguajes de programación aparte de los con que fue creado en mente: Julia, Python y R. Inclusive se puede utilizar junto con C#... aunque el soporte todavía no es muy bueno. 30 | 31 | Si eres fan de C#, existe algo muy parecido pero lamentablemente no tiene tanta flexibilidad como los Notebooks de Jupyter, se llaman los Xamarin Workbooks, escribí un post sobre ellos, dejo el enlace en la descripción. 32 | 33 | Pero bueno, si quieres comenzar a usar los Notebooks pero eres un novato como yo, mi recomendación es que instales [Anaconda](http://jupyter.readthedocs.io/en/latest/install.html#id3), que es otra gran herramienta, pero de la cual por el momento solo nos interesa usar los Notebooks. En la siguiente parte de este video les mostraré en un Notebook en acción. -------------------------------------------------------------------------------- /content/posts/2015-11-02-que-son-portable-class-library.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: ¿Qué es una Portable Class Library? 4 | date: 2015-11-02 10:00:00 5 | author: Antonio Feregrino 6 | categories: c-sharp visual-studio 7 | summary: Las bibliotecas de clases portables nos permiten compartir código entre distintas plataformas de .NET 8 | lang: es 9 | github: https://github.com/fferegrino/pcls 10 | featured_image: featured.png 11 | tweet_id: 661730211222810624 12 | tags: VisualStudio 13 | featured_tag: VisualStudio 14 | --- 15 | 16 | Imaginémonos esto: 17 | 18 | Supongamos que es nuestra tarea desarrollar una calculadora (que suma dos números) en C# para varias plataformas, entre ellas: 19 | 20 | - Android (con Xamarin.Android) 21 | - Consola de Windows 22 | - Sitio Web 23 | 24 | Estas tres son plataformas radicalmente distintas, cada una tiene características que son únicas para ella y es por eso que hasta hasta hace poco tiempo, nuestra única opción para desarrollar nuestra calculadora era escribirla una vez para cada plataforma, una librería para cada uno... algo así: 25 | 26 | 27 | 28 | Como podemos ver, debíamos escribir el mismo código tres veces a pesar de ser el mismo lenguaje, y si en el futuro se nos ocurría llevar nuestra calculadora a Xbox tendríamos que reescribir otra vez nuestro código para dicha plataforma. 29 | 30 | ## PCL 31 | Sin embargo todo cambió con la aparición de las PCL (**Portable** Class Library o Biblioteca de Clases Portable), que nos permiten compartir código entre distintas plataformas de `.NET` a través de una sola librería ("una sola dll", podríamos decir). Con ella podemos hacer algo como esto: 32 | 33 | 34 | 35 | Y esto es gracias a que nuestra calculadora es bastante simple, para hacer el cálculo no necesitamos leer datos de consola, ni acceder al GPS del celular ni menos montar un servidor nuestra página. 36 | 37 | ### Creando una PCL 38 | Desde Visual Studio tebemos ir a `Archivo / File` → `Nuevo / New` → `Proyecto / Project` 39 | 40 | 41 | 42 | Poseriormente aparecerá una pequeña ventana con varias casillas de verificación a través de las cuales debemos elegir las plataformas sobre las que queremos que nuestra librería funcione, una vez elegidas damos click en Aceptar 43 | 44 | 45 | 46 | Y listo, solo queda referenciar a nuestra biblioteca desde nuestros proyectos. 47 | 48 | 49 | ### Limitaciones 50 | Como podemos ver, al momento de crear una *biblioteca portable* debemos elegir sobre qué plataformas queremos que funcione y es quen es mediante esta selección estamos limitando la cantidad de características del framework .NET a las que vamos a tener acceso desde ella, en esta imagen se explica un poco mejor: 51 | 52 | 53 | 54 | La *biblioteca portable* siempre tomará la menor cantidad de características posibles para funcionar en todas las plataformas elegidas. 55 | 56 | ### Usos 57 | En el ejemplo de este post usé una calculadora (que suma únicamente dos números) pero en realidad pude haber puesto en una PCL cualquier cosa, desde la llamada a un web service hasta un cálculo matemático más complejo. Por cierto, el código de este post está en GitHub. 58 | 59 | Las posibilidades de uso son muchísimas, diversos paquetes de NuGet se benefician de estar hechos en PCLs permitiéndoles así poder ser instalados en varias plataformas usando un mismo ensablado. 60 | 61 | Entre los diversos usos que se le pueden dar a una PCL está el de contener nuestras vistas en Xamarin.Forms, en este caso, la librería se comparte entre los proyectos de Xamarin.Android, Xamarin.iOS y Windows Phone. -------------------------------------------------------------------------------- /content/posts/tv/2018-01-27-dormir-programar.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ¿Dormir o programar? 3 | date: 2018-01-27 18:00:00 4 | youtube_id: cgUjxwyltiI 5 | summary: No dormir no es una medalla de honor, y el hecho de no dormir lo suficiente por estar trabajando o haciendo tarea no debe presumirse como un logro. 6 | tweet_id: 957991779667718144 7 | tags: Meta, YouTube 8 | featured_tag: Tv 9 | layout: video 10 | --- 11 | 12 | Este es un video más como de opinión, y quisiera comenzar diciendo esto: no dormir no es una medalla de honor, y el hecho de no dormir lo suficiente por estar trabajando o haciendo tarea no debe presumirse como un logro. Esto podría sonar raro, pero me parece que es algo muy común en el el ambiente de la programación de aplicaciones, aunque también lo he escuchado en otras profesiones, como entre los médicos. 13 | 14 | Claro, hay veces en que puede ser necesario: te encontraste con algo que es realmente complicado, tal vez tuviste que ayudar a alguien más o cuidar de tus hijos... También hay ocasiones en las que quedarse despierto puede ser divertido, como es el caso de algunos hackatones, conferencias o, las ya viejas, LAN parties. Sea cual sea la razón, a veces es necesario o divertido quedarse despierto, pero en mi opinión, no debes dejar que se convierta en un modo de vida. 15 | 16 | Hubo una etapa en mi vida en la que pensaba que dormir era una pérdida de tiempo: siempre tenía que "estar haciendo algo productivo"; pero eso ha cambiado, pues resulta que me di cuenta de que dormir el tiempo correcto es hacer algo productivo, dormir el tiempo necesario es no es un gasto, sino una inversión, y una muy buena. Seguramente ya te has desvelado antes, y sabes lo terrible que se siente al día siguiente: 17 | 18 | - Estás de mal humor, 19 | - te duele la cabeza, 20 | - no te dan muchas ganas de hablar con nadie, 21 | - te sientes desanimado y sin creatividad, 22 | - y te resulta imposible concentrarte... 23 | - ¡además de que te andas quedando dormido en todos lados! 24 | 25 | Pero bueno, piénsalo... si algo se te complicó y empezaste a trabajar por la tarde y la noche se aproxima, cuando menos de das cuenta comienzas a tener sueño y a bostezar, ¿qué haces? ¿te vas a dormir? O, si ya trabajas, ¿qué pasa si por alguna razón el desarrollo de un módulo se retrasó y el cliente ya lo espera para la mañana siguiente? Cualquier escenario que te lleve al extremo ¿o vas por una lata de RedBull o una taza de café para seguir trabajando? ¿Qué haces normalmente, cuéntanos en los comentarios? ¿Te ha pasado algo similar o sueles desvelarte, cuéntanos? 26 | 27 | En mi opinión, muchas veces el tener que quedarse despierto para terminar algo es algo que puede atacarse de manera productiva, y si te toca desvelarte muy seguido por esta razón, deberías tratar de encontrar las causas que te llevan a no dormir para tratar de eliminarlas. 28 | 29 | También es cierto, y volviendo a lo que comenté al inicio del video, muchas compañías hacen de el no dormir una especie de medalla invisible, y digo invisible porque la verdad es que dudo mucho que alguien se atreva a poner un cuadro del tipo "empleado del mes" pero que diga "el que menos duerme". Este tipo de medallas es algo que a veces nos presumimos entre nosotros, no se imaginan la cantidad de veces que oí, y yo mismo dije: "Me quedé despierto hasta las tres haciendo esto" o "Wey, llevo dos días sin dormir por terminar X o Y", al principio puede sonar divertido y ser un motivo de orgullo, pero con el tiempo esto no va a hacer nada más que afectar tu desempeño y salud. 30 | 31 | Aunque a veces también pasa que te sientes taaaan inspirado que prefieres terminar lo que estás haciendo antes de ir a dormir, mi consejo es: No lo hagas, no vale la pena sacrificar una parte de (o todo) el día siguiente por trabajar dos o tres horas más durante la noche. Mi recomendación es que te tomes 5 minutos para escribir tu idea en la parte del código en la que estás trabajando, o de plano agarres una hoja de papel y la escribas ahí, y una vez hecho esto, te vayas a dormir sin remordimientos. Si la idea que tenías en mente antes de dormir era tan buena, cuando te despiertes por la mañana va a seguir ahí. 32 | 33 | Si dormir el tiempo necesario para descansar es un lujo que tu te puedes dar, créeme, dátelo. Duerme lo necesario, tu teclado (y el problema que estás enfrentando) seguirá ahí a la siguiente mañana. -------------------------------------------------------------------------------- /content/posts/tv/2018-06-19-text-as-data.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Text as data 3 | date: 2018-06-19 18:00:00 4 | youtube_id: LZhTBxso3Ys 5 | categories: data-science 6 | summary: The first thing is to learn how to organise and categorise text. The second was how to search and retrieve the documents or fragments of them, and the third one was how to analyse the text to extract the sentiments that the authors were expressing. 7 | lang: en 8 | tags: Data science, Meta, YouTube 9 | featured_tag: Tv 10 | layout: video 11 | --- 12 | 13 | # Text as Data 14 | Text as data... a kind of a generic name to talk about text analysis & text classification. 15 | 16 | The idea behind this course was to teach us the basics of three things taking into consideration that in the real world, information is in significant part contained in text documents: 17 | 18 | The first thing is to learn how to **organise and categorise** text. The second was how to **search and retrieve** the documents or fragments of them, and the third one was how to **analyse** the text to extract the sentiments that the authors were expressing. 19 | 20 | ## Lecture 1. Introduction to text 21 | In the first lecture, we reviewed how can text be represented as **sparse vectors**, how can we calculate different **similarity measures** between two vectors using similarity measures of sets. After that, we checked the **bag of words** representation, as well how can we go beyond working with single, tokenised words and consider pairs or triples of words using **n-grams** and another similarity measure, the **cosine similarity**. We finalised this lecture by reviewing the problems with using term frequency as the only criteria to describe our documents. 22 | 23 | ## Lecture 2. Text distributions 24 | As we learned in the previous lecture, using the *raw term frequency* is not the best idea, and thus, in this lecture, we saw different options to overcome this issue, such as **operating in the log space** for the term frequency, as well as how to consider the collection using something known as the **inverse document frequency or IDF**. 25 | 26 | ## Lecture 3. Distributions and clustering 27 | Following with term distribution, we saw how it could be used to cluster documents in an unsupervised manner using algorithms such as k-means or hierarchical clustering. 28 | 29 | ## Lecture 4. Language Modelling 30 | For the fourth lecture, we learned another approach to representing documents and that is through probabilities: the probability of a sequence of words and the probability of a word given a sequence of words, via Language Models, and how considering n-grams allows us to get better models. 31 | 32 | ## Lecture 5. Word Vectors 33 | In lecture number five we learned about word embeddings, which is a somewhat more modern approach of representing words as dense vectors, created from the context of each word. 34 | 35 | ## Lecture 6. Text classification 36 | Lecture six was about classification; we briefly reviewed classifiers such as Naïve Bayes, logistic regression, SVM and decision trees. 37 | 38 | ## Lecture 7. Intro to NLP 39 | Natural Language Processing was the topic of the seventh lecture, in this case, things like including part of the speech tagging and dependency parsing. 40 | 41 | ## Lecture 8. More on text classification 42 | Lecture eight was another look at classification, reviewing some good practices to avoid over or underfitting, as well as some ethical concerns that may arise from using machine learning for real-world applications. 43 | 44 | ## Lecture 9. More on clustering 45 | Just like the previous lecture, this one was about revisiting an old lecture from another perspective, in this case: clustering using **Latent Semantic Indexing**. 46 | 47 | ## Applications 48 | The last lectures were about applications of what we saw during the course: 49 | 50 | ### Lecture 10. Information Extraction, Named Entity recognition and Relation Extraction 51 | 52 | ### Lecture 11. Question Answering, and QA architectures 53 | 54 | ### Lecture 12. Dialogue Systems, chatbots, slot filling 55 | 56 | ## Labs. 57 | The labs for this course were by far the most interesting of any other course I had this semester (don't feel bad Big Data, yours were cool as well). We worked with tools like NLTK and spaCy, and Google's version of the Jupyter Notebooks called Colab. 58 | --------------------------------------------------------------------------------