-
Notifications
You must be signed in to change notification settings - Fork 0
/
feed.xml
729 lines (475 loc) · 60.5 KB
/
feed.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>That CS guy</title>
<description>Escribo sobre ciencias computacionales, principalmente enfocado a la programación de aplicaciones, pero con énfasis en C#, mi lenguaje favorito. A veces me da por escribir sobre tecnología también.
</description>
<link>http://thatcsharpguy.com/</link>
<atom:link href="http://thatcsharpguy.com/feed.xml" rel="self" type="application/rss+xml"/>
<pubDate>Thu, 21 Jun 2018 07:55:15 +0100</pubDate>
<lastBuildDate>Thu, 21 Jun 2018 07:55:15 +0100</lastBuildDate>
<generator>Jekyll v3.8.2</generator>
<item>
<title>Text as Data</title>
<description><h1 id="text-as-data">Text as Data</h1>
<p>Text as data… a kind of a generic name to talk about text analysis &amp; text classification.</p>
<p>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:</p>
<p>The first thing is to learn how to <strong>organise and categorise</strong> text. The second was how to <strong>search and retrieve</strong> the documents or fragments of them, and the third one was how to <strong>analyse</strong> the text to extract the sentiments that the authors were expressing.</p>
<h2 id="lecture-1-introduction-to-text">Lecture 1. Introduction to text</h2>
<p>In the first lecture, we reviewed how can text be represented as <strong>sparse vectors</strong>, how can we calculate different <strong>similarity measures</strong> between two vectors using similarity measures of sets. After that, we checked the <strong>bag of words</strong> representation, as well how can we go beyond working with single, tokenised words and consider pairs or triples of words using <strong>n-grams</strong> and another similarity measure, the <strong>cosine similarity</strong>. We finalised this lecture by reviewing the problems with using term frequency as the only criteria to describe our documents.</p>
<h2 id="lecture-2-text-distributions">Lecture 2. Text distributions</h2>
<p>As we learned in the previous lecture, using the <em>raw term frequency</em> is not the best idea, and thus, in this lecture, we saw different options to overcome this issue, such as <strong>operating in the log space</strong> for the term frequency, as well as how to consider the collection using something known as the <strong>inverse document frequency or IDF</strong>.</p>
<h2 id="lecture-3-distributions-and-clustering">Lecture 3. Distributions and clustering</h2>
<p>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.</p>
<h2 id="lecture-4-language-modelling">Lecture 4. Language Modelling</h2>
<p>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.</p>
<h2 id="lecture-5-word-vectors">Lecture 5. Word Vectors</h2>
<p>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.</p>
<h2 id="lecture-6-text-classification">Lecture 6. Text classification</h2>
<p>Lecture six was about classification; we briefly reviewed classifiers such as Naïve Bayes, logistic regression, SVM and decision trees.</p>
<h2 id="lecture-7-intro-to-nlp">Lecture 7. Intro to NLP</h2>
<p>Natural Language Processing was the topic of the seventh lecture, in this case, things like including part of the speech tagging and dependency parsing.</p>
<h2 id="lecture-8-more-on-text-classification">Lecture 8. More on text classification</h2>
<p>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.</p>
<h2 id="lecture-9-more-on-clustering">Lecture 9. More on clustering</h2>
<p>Just like the previous lecture, this one was about revisiting an old lecture from another perspective, in this case: clustering using <strong>Latent Semantic Indexing</strong>.</p>
<h2 id="applications">Applications</h2>
<p>The last lectures were about applications of what we saw during the course:</p>
<h3 id="lecture-10-information-extraction-named-entity-recognition-and-relation-extraction">Lecture 10. Information Extraction, Named Entity recognition and Relation Extraction</h3>
<h3 id="lecture-11-question-answering-and-qa-architectures">Lecture 11. Question Answering, and QA architectures</h3>
<h3 id="lecture-12-dialogue-systems-chatbots-slot-filling">Lecture 12. Dialogue Systems, chatbots, slot filling</h3>
<h2 id="labs">Labs.</h2>
<p>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.</p>
</description>
<pubDate>Tue, 19 Jun 2018 19:00:00 +0100</pubDate>
<link>http://thatcsharpguy.com/tv/text-as-data/</link>
<guid isPermaLink="true">http://thatcsharpguy.com/tv/text-as-data/</guid>
<category>DataScience</category>
<category>Meta</category>
<category>Tv</category>
<category>tv</category>
<category>data-science</category>
</item>
<item>
<title>Apache Spark</title>
<description><h1 id="spark">Spark.</h1>
<p>Hace ya unos meses les platiqué de MapReduce, que es un framework para procesamiento de grandes sets de datos, en ese video también les hablé de las limitantes de este modelo como el trabajar con algoritmos iterativos o el procesar datos en “tiempo-real”.</p>
<p>Hoy les voy a hablar de otra forma de trabajar con grandes de cantidades de datos que es un poco distinta, esta vez utilizando Apache Spark. Spark es un framework de computación desarrollado inicialmente en la Universidad de California Berkeley, pero ahora es parte de los proyectos de la Apache Software Foundation.</p>
<p>Spark funciona al rededor de un concepto muy importante es el de los <strong>Resilient Distributed Datasets</strong> o <strong>RDDs</strong>, algo que podría ser traducido a datasets distribuidos y recuperables (?). Estos RDDs son colecciones de datos de solo lectura, es decir, una vez creados ya no son modificables, y cada vez que uno es “modificado” en realidad se está creando uno nuevo.</p>
<p>Estos RDDs no son creados de manera inmediata, sino que su creación se retrasa hasta que son <em>materializados</em>: es decir almacenados en memoria o en disco, o en algunos casos para realizar alguna operación con ellos. En un concepto muy muy parecido a la evaluación perezosa.</p>
<p>Su característica más importante es que en lugar de llevar un registro de la información que un RDD contiene, se lleva un registro de las operaciones que lo crearon, de este modo se puede ordenar la creación de un RDD nuevamente en caso de fallos.</p>
<p>A medida que se van creando RDDs, también se va creando un grafo dirigido y aciciclico, o en terminología de Spark: <strong>DAG</strong>, este grafo es una manera de representar las operaciones sobre los RDDs que les acabo de mencionar. Cuando un RDD es materializado el sistema se encarga de decidir cuál es la manera más óptima de crearlo a partir de las operaciones con las que se especificaron sobre él y sus derivados.</p>
<h2 id="distribuido">Distribuido</h2>
<p>Cabe señalar que al igual que MapReduce, Spark también es ejecutado en un cluster de servidores y que existe toda una pesadilla de orquestación para que este funcione correctamente, para tu buena suerte esta tarea ya está resuelta y tu solamente te puedes enfocar en resolver tu problema (la mayoría de las veces).</p>
<p>Es justamente el DAG el que va a definir cómo es que los datos se van a mover entre nodos, reduciendo en lo mayor posible el movimiento de información entre servidores.</p>
<h2 id="ejemplo">Ejemplo</h2>
<p>Otra de sus ventajas es que al contrario de MapReduce con Spark no necesitas diseñar por separado las partes del sistema, puedes tratar to código como si estuvieras desarrollando un sistema monolítico y sin alguna consideración extra, cierto es que para lograr un buen desempeño es necesario que lidies con asuntos de distribución de cargas y repartición de trabajo, pero para empezar a programar no necesitas saber esto, además de que el código es mucho más sencillo de leer y de escribir.</p>
<p>Este es el ejemplo de el conteo de palabras en Spark usando los tres lenguajes que Spark soporta por default:</p>
<h3 id="scala">Scala</h3>
<pre><code>val textFile = sc.textFile("hdfs://...")
val counts = textFile.flatMap(line =&gt; line.split(" "))
.map(word =&gt; (word, 1))
.reduceByKey(_ + _)
counts.saveAsTextFile("hdfs://...")
</code></pre>
<h3 id="python">Python</h3>
<pre><code>text_file = sc.textFile("hdfs://...")
counts = text_file.flatMap(lambda line: line.split(" ")) \
.map(lambda word: (word, 1)) \
.reduceByKey(lambda a, b: a + b)
counts.saveAsTextFile("hdfs://...")
</code></pre>
<h3 id="java">Java</h3>
<pre><code>JavaRDD&lt;String&gt; textFile = sc.textFile("hdfs://...");
JavaPairRDD&lt;String, Integer&gt; counts = textFile
.flatMap(s -&gt; Arrays.asList(s.split(" ")).iterator())
.mapToPair(word -&gt; new Tuple2&lt;&gt;(word, 1))
.reduceByKey((a, b) -&gt; a + b);
counts.saveAsTextFile("hdfs://...");
</code></pre>
<p>Como puedes ver no es necesario dividir tu código en mapper y reducer como tendrías que haberlo hecho con MapReduce</p>
<pre><code> public static class TokenizerMapper
extends Mapper&lt;Object, Text, Text, IntWritable&gt;{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context
) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
public static class IntSumReducer
extends Reducer&lt;Text,IntWritable,Text,IntWritable&gt; {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable&lt;IntWritable&gt; values,
Context context
) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
</code></pre>
<h2 id="spark-vs-mapreduce">Spark vs. MapReduce</h2>
<p>Pero bueno, por todo lo que he dicho pareciera que debemos todos dejar de usar MapReduce (y en la mayoría de los casos esto parece ser un buen consejo) pero en general debes saber que Spark usa muchísima memoria RAM para cumplir su cometido eficientemente mientras que MapReduce utiliza memoria de disco que es aún un poco más barata, además de que si no necesitas velocidad en el procesamiento de la información considerar Spark podría ser una exageración.</p>
<h2 id="key-value-pairs">key-value pairs</h2>
<p>Se podría decir que Spark es compatible con MapReduce gracias a los tipos de dato llave-valor, así como el hecho de que podemos usar los mismos conectores de lectura de archivos. Por lo que algunas de las cosas que se hacen con MapReduce son directamente portables a Spark. Pero en fin, sigamos hablando de los beneficios de Spark…</p>
<h2 id="extensiones">Extensiones</h2>
<p>Spark ofrece algunas extensiones que lo habilitan para trabajos relacionados con SQL y DataFrames, Machine Learning, Streaming de datos y grafos.</p>
<h2 id="streaming">Streaming</h2>
<p>En el video de MapReduce me dejaron esta pregunta y respondí que Spark era una alternativa, y es que como mencioné esta herramienta permite trabajar con flujos de datos en <em>tiempo real</em>… pero de esto podemos hablar en otro video, a lo mejor y hasta con un screencast.</p>
</description>
<pubDate>Tue, 12 Jun 2018 19:00:00 +0100</pubDate>
<link>http://thatcsharpguy.com/tv/spark/</link>
<guid isPermaLink="true">http://thatcsharpguy.com/tv/spark/</guid>
<category>DataScience</category>
<category>Meta</category>
<category>Tv</category>
<category>tv</category>
<category>big-data</category>
</item>
<item>
<title>Big Data</title>
<description><h1 id="big-data">Big Data</h1>
<p>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.</p>
<p>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.</p>
<p>Starting with…</p>
<h2 id="google-file-system">Google File System</h2>
<p>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.</p>
<p>From there we jumped to …</p>
<h2 id="hdfs-or-hadoop-file-system">(HDFS) or Hadoop File System</h2>
<p>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!).</p>
<p>Once we learned a bit about HDFS, we learned about his companion, the programming model called…</p>
<h2 id="mapreduce">MapReduce</h2>
<p>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.</p>
<p>However, MapReduce is somewhat outdated too, and it has some limitations. We reviewed other more modern approaches to work with Big Data problems using…</p>
<h2 id="spark">Spark</h2>
<p>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.</p>
<p>Both MapReduce and Spark run on top of a distributed filesystem, benefitting themselves from the characteristics of such systems.</p>
<p>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…</p>
<h2 id="bigtable">Bigtable</h2>
<p>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.</p>
<p>Again we briefly saw an open source version of Bigtable called <strong>HBase</strong>.</p>
<h2 id="cassandra">Cassandra</h2>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
</description>
<pubDate>Tue, 12 Jun 2018 19:00:00 +0100</pubDate>
<link>http://thatcsharpguy.com/tv/big-data/</link>
<guid isPermaLink="true">http://thatcsharpguy.com/tv/big-data/</guid>
<category>DataScience</category>
<category>Meta</category>
<category>Tv</category>
<category>tv</category>
<category>big-data</category>
</item>
<item>
<title>Information Retrieval</title>
<description><h1 id="information-retrieval">Information retrieval</h1>
<p>Well, the title is self-explanatory but a good definition is the following: information retrieval is a field concerned with the structure, analysis, organisation, storage, searching and retrieval of information. In this case, we focused on textual information.</p>
<p>We started by looking at the…</p>
<h2 id="architecture-of-ir-systems">Architecture of IR systems</h2>
<p>And its three components: Query terms, a collection of documents and the retrieval system. Then we continued with the critical parts of its operation:</p>
<h3 id="document-processing">Document processing</h3>
<p>We need to prepare the documents to be retrieved, and this is done through a series of steps: the first one is <strong>tokenisation</strong> that is: converting sentences into words, <strong>stopword removal</strong>: getting rid of highly frequent words and finally, <strong>conflation/stemming</strong> taking similar words and transform them into a single unique symbol.</p>
<p>All of this to create a structure called the <strong>Inverted index</strong>.</p>
<h3 id="inverted-index">Inverted index</h3>
<p>The inverted index is a structure that maps words to the documents where they appear. I won’t go into much detail about inverted indexes in this video but if you want to know more, just let me know in the comments.</p>
<h3 id="retrieving">Retrieving</h3>
<p>Finally, we took a look at one of the basic algorithms for document retrieval given a query: the <em>best-match</em> algorithm that only considers whether a document contains or not a word of the query we are evaluating. However, most of the time this approach is not a good idea, and we then reviewed <strong>term weighting</strong>.</p>
<h2 id="term-weighting">Term Weighting</h2>
<p>The idea behind term weighting is to give each word a value that represents its importance for a document. To understand a bit more this idea we first studied the <strong>Zipf’s law</strong> and how it applies to vast collections of texts.</p>
<p>After that, we learned about the heuristic of using something known as <strong>Inverse Document Frequency</strong> to take into consideration the assumption that if a term appears many times in different documents in the collection, it is less representative of a single document.</p>
<h2 id="vector-space-model">Vector Space Model</h2>
<p>We also saw another way to represent documents: as high dimensional vectors, where each one of these dimensions represents the words in our whole vocabulary. Operating in a vector space allows us to compute similarities between other documents and queries.</p>
<p>However, what’s the idea behind building a retrieval system if there is no way to evaluate it?</p>
<h2 id="evaluation">Evaluation</h2>
<p>With this in mind, we took a look at how are retrieval systems evaluated. Starting from the creation of <strong>test collections</strong>, that are extensive collections of documents accompanied by queries and relevance assessments, provided by humans.</p>
<p>Metrics such as Precision @ rank R, Precision at standard recall levels, and Average precision and their averaged values, like Mean Average Precision and Mean Reciprocal Rank or the Discounted Cumulative Gain.</p>
<h2 id="relevance-feedback">Relevance Feedback</h2>
<p>Then we saw how to improve, or at least try to improve, the results our system outputs by using feedback from the user, something called <strong>relevance feedback</strong>. Specifically, three different kinds of feedback: <strong>Explicit feedback</strong>, <strong>implicit feedback</strong> and <em>pseudo-relevant feedback</em> and their relationship to <strong>query expansion</strong>.</p>
<p>Following the trend of involving the user in the retrieval process we looked into <strong>Interactive IR</strong>, and some other ways to involve the user in the process of information retrieval, mainly through the user interface of the results output. After this, we went back to other, in this case, <em>advanced retrieval models</em>…</p>
<h2 id="advanced-retrieval-models">Advanced Retrieval Models</h2>
<p>All the retrieval models we had seen so far were… simple.</p>
<p>In this section, we started taking into account probability and considering the relevance estimation as a classification problem. Using retrieval models like BM25 or Language models, or even some more advanced ones like PL2, part of the Divergence From Randomness framework. This, also considering proximity between terms in an attempt to improve search results.</p>
<h2 id="learning-to-rank">Learning to Rank</h2>
<p>Moreover, we can use machine learning to refine the final ranking shown to the user. We reviewed the <em>cascade-like</em> pipeline to filter documents to prepare our machine learning models what kind of features we can use and the three kinds of learning tasks: Pointwise, Pairwise and Listwise.</p>
<p>For a while, we focused on <strong>web search</strong> and its challenges. Like personalising the results for each user, or considering the context the user is in to resolve ambiguities. Keeping on with web search, we studied a way to get documents through <strong>web crawling</strong> which is not an easy task. You need to consider issues like respecting the servers you’re querying or withstand traps in the web or malformed htmls, not to mention the fact that we need to keep track of the documents we’ve downloaded, and that we can’t do it at high scale with a single computer.</p>
<p>Then we went back to evaluation…</p>
<h2 id="online-evaluation">Online evaluation</h2>
<p>The evaluation that we studied earlier in the course is known as offline evaluation, but a more exciting and challenging task is to evaluate our system while real users are using it. We reviewed two techniques: A/B testing and Interleaving.</p>
<h2 id="ir-infrastructures-and-efficiency">IR infrastructures and efficiency</h2>
<p>After all we saw, we had to review how to make them efficient by reviewing compression techniques for the index such as <strong>pruning</strong> or <strong>unary or gamma coding</strong>, as well as caching techniques for queries, terms or documents. We saw some of the infrastructures and how they affect the performance and evaluation of the queries that are issued to the system.</p>
<h2 id="real-time-ir">Real-time IR</h2>
<p>We saw the necessity and challenges of performing some of the tasks we previously saw but using streams of data, such as tweets or facebook status updates.</p>
<h2 id="applications-beyond-search">Applications Beyond Search</h2>
<p>To finalise the course, we were introduced to other applications such as Text summarisation, real-time event detection, Recommendations and Question Answering.</p>
<p>So that was about it, on the practical side of things we worked with Terrier, with is a retrieval system developed here at the University of Glasgow.</p>
</description>
<pubDate>Tue, 05 Jun 2018 19:00:00 +0100</pubDate>
<link>http://thatcsharpguy.com/tv/information-retrieval/</link>
<guid isPermaLink="true">http://thatcsharpguy.com/tv/information-retrieval/</guid>
<category>Meta</category>
<category>Tv</category>
<category>tv</category>
<category>c-sharp</category>
</item>
<item>
<title>Data Fundamentals</title>
<description><p>This is the first video of a series I’ll be uploading in the coming weeks about the courses that I took as part of my masters’ degree here at the University of Glasgow.</p>
<p>The first course I want to talk to you about is Data Fundamentals. Basically, this course was a refresher of some of the things that you learned if you did an engineering degree, not to mention if you did a computer science degree. In my opinion, this was also the perfect introduction to Data Science, with basic but very interesting stuff that prepared us for the challenges.</p>
<p>I think it is worth mentioning that this was by far my favourite course, not only because of the topics we reviewed but also because of the lecturer, John Williamson, the way he explained things to us was simply amazing. But anyways, here in the university, the courses are divided in lectures. Usually, there is one topic per lecture, and it is precisely in that way that I’ll be describing them to you.</p>
<p>Starting with lecture 1:</p>
<p><strong>Lecture 1</strong>: We saw how to work with NumPy, a practical library to deal with numerical data in the form of arrays (vectors, matrices and tensors) using Python, how to transform them by performing flipping, slicing, transposing, and many more operations on them. And we also took a brief look at the concept of vectorized computing, which allows performing a single operation to multiple data elements to improve the performance of our code by taking the maximum advantage of our computers.</p>
<p>For the <strong>Lecture 2</strong>: we learned how arrays are efficiently stored in a computer, we also saw how floats are stored in IEEE 754 notation, and this enabled us to know what are the most common errors that could happen when working with them. Finally, we were introduced to the concept of higher rank tensors, and how can we work efficiently with them using vectorized computing.</p>
<p>In <strong>Lecture 3</strong>: we were shown some basics of scientific visualisation using <code>matplotlib</code> a Python library to plot data, and learned the “language” of graphics, what is a stat, a scale, a guide, a geom, layer and a facet. As well as which plots make more sense when dealing with different types of data, this also involved which colours we can use to correctly communicate our findings when working with data.</p>
<p>The <strong>Fourth lecture</strong> was about an introduction to linear algebra, its concepts and how can we perform them using Python and NumPy. This is somewhat an extension of what we saw in the first lecture, but now with linear algebra in mind. In here we reviewed the basic operations that can be performed on vectors, the concept of norm and more complex vector operations. By the end of this lecture we reviewed matrices and the operations that are defined for them as well as some useful properties that we can use to make our computations simpler.</p>
<p>The <strong>Fifth lecture</strong> started with a refresher of how graphs can be represented using matrices whether they are directed, undirected and weighted or unweighted. After that, we went back directly to linear algebra, where concepts like eigenvalues and eigenvectors appeared, and how they are related to Principal Component Analysis. Talking about decomposition of matrices, we also reviewed the concept of Singular Value Decomposition, a way to decompose a matrix into simpler forms to enable efficient computation on them.</p>
<p>In <strong>Lecture 6</strong>, we started with the core concept in which machine learning relies on optimization. Optimization is the task of finding the optimal settings for a process in order to improve it. We saw the main parts of an optimization problem:</p>
<ul>
<li>Parameters</li>
<li>Objective function</li>
</ul>
<p>For this, we also saw how can constraints be implemented into our parameter selection to make our optimization search more realistic. We focused mainly on iterative optimization, guided by heuristics that try to improve the performance of the algorithms behind them.</p>
<p><strong>Lecture 7</strong> was also about optimization concepts, including the basics of how a neural network works, and how derivatives can help us in finding the optimal parameters using the gradient descent algorithm. We saw what differentiable programming is and how we can use it to perform optimization.</p>
<p>In <strong>Lecture 8</strong> the topic was probability, starting from the basics, including the concept of probability mass functions and probability density functions. We also reviewed what the joint, marginal and conditional probability, the basis for the Bayes’ Rule, a very important concept as well. And how can we deal with probabilities without running into numerical issues.</p>
<p>In the <strong>lab number eight</strong>, corresponding to this lecture, we learned what a stochastic process was, and practised using a specific version of this kind of processes: the Markov process.</p>
<p><strong>Lecture 9</strong> was also about probability; we saw the concept of expectation, then some statistics and finally what Bayesian inference is and the Monte Carlo approaches are useful when dealing with Bayesian inference.</p>
<p>To conclude with the course in the <strong>lecture number 10</strong>, in we saw a bit of Digital Signals processing and time series. What sampling is and its relationship with the Nyquist limit, and how aliasing can appear if we don’t respect this limit. The last section of this lecture was about convolution and the Fourier transform.</p>
<p>Of course, we reviewed a lot more topics and we went more in-depth for almost all of them, trying to summarize hours of lectures and labs in a short video is not that easy, so if you want to know more about something that I mentioned where, please leave it on the comments.</p>
<p>So, that’s it for me, at least for now, I hope you liked this video, and if you did, please give it a Like. There are more videos coming about the remaining courses that I’m creating as I review the lecture notes in preparation for the exam, I think the next one is going to be about machine learning.</p>
</description>
<pubDate>Thu, 05 Apr 2018 19:00:00 +0100</pubDate>
<link>http://thatcsharpguy.com/tv/data-fundamentals/</link>
<guid isPermaLink="true">http://thatcsharpguy.com/tv/data-fundamentals/</guid>
<category>Meta</category>
<category>Tv</category>
<category>tv</category>
</item>
<item>
<title>¿Programar en inglés?</title>
<description><p>Los algoritmos voraces o <em>greedy</em> son algoritmos que implementan una heuristica(técnica) que tiene como objetivo optimizar la búsqueda de una solución óptima para un problema.</p>
<p>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.</p>
<p>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.</p>
<p>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:</p>
<p>A cada paso, comprar el boleto más barato hasta llegar al pueblo Y.</p>
<h3 id="no-siempre-es-lo-mejor">No siempre es lo mejor</h3>
<p>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í.</p>
<p>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:</p>
<p>Tomando nuevamente el boleto más barato, aunque al final, estas decisiones localmente óptimas lo llevaron a gastar más dinero.</p>
<h3 id="por-qué-existen">¿Por qué existen?</h3>
<p>Pero bueno, si al final puede que no obtenga el mejor resultado, ¿por qué existe esta técnica?</p>
<p>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.</p>
<p>También existen porque en general son sencillos de entender y también sencillos de programar.</p>
<p>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.</p>
<h3 id="los-componentes">Los componentes</h3>
<p>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:</p>
<ul>
<li>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.</li>
</ul>
<h3 id="ejemplos">Ejemplos</h3>
<p>Entre los ejemplos que encontrarán sobre problemas que se pueden afrontar con estos algoritmos están:</p>
<p>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.</p>
</description>
<pubDate>Tue, 20 Mar 2018 18:00:00 +0000</pubDate>
<link>http://thatcsharpguy.com/tv/programar-ingles/</link>
<guid isPermaLink="true">http://thatcsharpguy.com/tv/programar-ingles/</guid>
<category>Meta</category>
<category>Tv</category>
<category>tv</category>
</item>
<item>
<title>Los algoritmos voraces</title>
<description><p>Los algoritmos voraces o <em>greedy</em> son algoritmos que implementan una heuristica(técnica) que tiene como objetivo optimizar la búsqueda de una solución óptima para un problema.</p>
<p>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.</p>
<p>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.</p>
<p>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:</p>
<p>A cada paso, comprar el boleto más barato hasta llegar al pueblo Y.</p>
<h3 id="no-siempre-es-lo-mejor">No siempre es lo mejor</h3>
<p>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í.</p>
<p>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:</p>
<p>Tomando nuevamente el boleto más barato, aunque al final, estas decisiones localmente óptimas lo llevaron a gastar más dinero.</p>
<h3 id="por-qué-existen">¿Por qué existen?</h3>
<p>Pero bueno, si al final puede que no obtenga el mejor resultado, ¿por qué existe esta técnica?</p>
<p>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.</p>
<p>También existen porque en general son sencillos de entender y también sencillos de programar.</p>
<p>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.</p>
<h3 id="los-componentes">Los componentes</h3>
<p>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:</p>
<ul>
<li>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.</li>
</ul>
<h3 id="ejemplos">Ejemplos</h3>
<p>Entre los ejemplos que encontrarán sobre problemas que se pueden afrontar con estos algoritmos están:</p>
<p>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.</p>
</description>
<pubDate>Sun, 11 Mar 2018 18:00:00 +0000</pubDate>
<link>http://thatcsharpguy.com/tv/algoritmos-voraces/</link>
<guid isPermaLink="true">http://thatcsharpguy.com/tv/algoritmos-voraces/</guid>
<category>Meta</category>
<category>Tv</category>
<category>tv</category>
</item>
<item>
<title>¿Qué es MapReduce?</title>
<description><p>Es un modelo de programación fuertemente orientado a la ejecución paralela y distribuida entre múltiples computadoras, que se utiliza para trabajar con grandes colecciones de datos, digamos, de unos cuantos terabytes (o petabytes). La idea de MapReduce es ofrecer una forma simple, rápida, escalable y resistente a fallos para manipular enormes cantidades de datos. En la terminología de MapReduce a estas manipulaciones se les conoce como trabajos, y así me referiré a ellos de ahora en adelante.</p>
<p>MapReduce surgió de Google y fue presentado en 2004 por dos investigadores de Google, quienes lo publicaron en un paper y fue a partir de ahí que se comenzó a desarrollar en el mundo del open source a partir de ahí se generó una propuesta open source que funciona dentro de Hadoop (que por cierto es otra maravilla del Open Source originada en Google, de la cual si quieren les hablo en otro video). La realidad es que la explicación que voy a dar aquí es muy, muy básica, y los invito a leer el paper y a buscar más información y desde luego, a dejar sus preguntas en los comentarios, no es que yo pueda responderlas, pero seguro yo se las puedo preguntar a alguien más.</p>
<h2 id="composición">Composición</h2>
<p>Su nombre proviene de dos viejos conocidos de la programación funcional: las funciones Map y Reduce. Como su nombre lo indica, se compone de dos etapas (en realidad hay tres, pero la tercera es transparente para el desarrollador): la etapa de Map o Mapeo y la etapa de Reduce o Reducción, un poco más adelante les hablaré a detalle de estas etapas.</p>
<p>Como lo mencioné antes, MapReduce fue creado para ejecutarse en múltiples computadoras a la vez, distribuyendo así la carga del trabajo en ellas, cabe destacar que estas computadoras no tienen que ser supercomputadoras carísimas, sino que pueden ser computadoras simples y relativamente baratas, es por eso que cuando se habla de MapReduce, se habla de clusters de computadoras.</p>
<p>Todas las computadoras que participan en un trabajo de MapReduce contienen un agente que coordina sus recursos, conocido como el NodeManager, este NodeManager a su vez se comunica con el encargado de orquestar todo el trabajo, que es nada más y nada menos que otra computadora dentro del cluster, que contiene un programa llamado ResourceManager, encargado de orquestar toda la operación de un trabajo de MapReduce (este asigna los trabajos, se mantiene al tanto de el estado de cada uno de los NodeManagers y resigna un trabajo no completado si es que alguno de los nodos deja de responder).</p>
<h2 id="entradas-y-salidas">Entradas y salidas.</h2>
<p>Como igual mencioné brevemente al inicio del video, un trabajo de MapReduce tiene como objetivo el tomar una cantidad de datos (de un archivo, de una base de datos o cualquier otra fuente de datos), manipularla de alguna manera y entregar un resultado al final. Pese a lo que indica su nombre “reduce”, el archivo generado no necesariamente tiene que ser una versión reducida de la entrada, puede llegar a ser más grande.</p>
<p>Su funcionamiento es más o menos el siguiente:</p>
<h3 id="mapping">Mapping</h3>
<p>De tu entrada de datos tomas un conjunto de información que tiene la forma de pares llave-valor, dentro de la fase del mapper realizas alguna especie de procesamiento sobre ellos, como podría ser separar una cadena por espacios en blanco, encontrar todos los links que contiene un documento web. La idea es que del mapper generes un nuevo conjunto de datos, de nuevo en la forma de llave-valor, aquí cabe señalar que no es necesario que las llaves ni los valores sean los mismos que en los archivos de entrada, pueden ser totalmente diferentes.</p>
<h3 id="shuffling">Shuffling</h3>
<p>A la salida de los mappers se ejecuta otra etapa, conocida como shuffling, que se encarga de ordenar los datos generados de acuerdo a la llave que tu les asignaste en el mapper. Una vez que se ejecutó la fase de shuffling, los datos están listos para ser consumidos por los reducers.</p>
<h3 id="reducing">Reducing</h3>
<p>La tarea de los reducers comienza al ir a recuperar la información de los mappers, cada reducer tendrá la tarea de procesar todos los datos asignados a una sola llave a la vez. En el Reducer tenemos la oportunidad de realizar otro procesamiento sobre los valores, pero ahora con la certeza de que toda la información que tenemos está identificada con una sola llave.</p>
<p>El reducer, al igual que el mapper, tiene la tarea de generar un nuevo conjunto de información en la forma llave-valor, la cual es depositada nuevamente en un archivo.</p>
<h2 id="claves">Claves</h2>
<p>Sí, sé que ese asunto de las llaves-valor puede sonar complicado al inicio, pero después de haber implementado una versión muy básica del primer PageRank de Google en MapReduce (dejo el link al post en la descripción) puedo identificar algunas claves:</p>
<ul>
<li>Pensar en forma paralela, y tratar de olvidar temporalmente todos los otros paradigmas que tengas en mente.</li>
<li>Que al momento de trabajar en los mappers no vas a tener toda la información que necesitas en un solo lugar, ve a los mappers como una etapa de preparación de la información.</li>
<li>Que si quieres que algo se ejecute en un solo lugar, eso sería del lado de los reducers, y para que esto suceda todos los elementos que quieres en un lugar deben tener la misma llave.</li>
</ul>
<h2 id="el-hola-mundo">El Hola Mundo</h2>
<p>El hola mundo del MapReduce es un ejemplo de conteo de palabras que te voy a tratar de explicar ahora mismo. Imagina que tienes el siguiente texto:</p>
<pre><code>Cuando cuentes cuentos
Cuenta cuantos cuentos cuentas
Por que si no cuentas cuantos cuentos cuentas
Nunca sabrás cuantos cuentos cuentas
</code></pre>
<p>Una forma de contar las palabras usando MapReduce es la siguiente:</p>
<p>Los mappers reciben fragmentos del texto, separados por lineas, la información es recibida de la siguiente manera, cada linea es un valor, y la llave de ese valor es el número de línea dentro del archivo. Dentro del mapper, tomamos cada línea y la separamos por espacios, tomamos cada una de esas palabras como llaves y les asociamos como valor un uno y los escribimos a la salida.</p>
<p>La tarea del shuffler será ordenar esta información por la llave , algo así:</p>
<p>Después, esta información es obtenida por los reducers, recuerda que los reducers tomarán todos los elementos asociados con una sola llave y los procesarán dentro de ellos.</p>
<p>En el reducer, se ejecuta un proceso que toma todos los números asociados a una palabra y los suma, tan solo para al final escribir a la salida otro par llave valor, en donde la llave es la palabra y el valor es el número de veces que aparece dicha palabra en el archivo.</p>
<h2 id="usos-y-limitaciones">Usos y limitaciones</h2>
<p>Por regla general se usa MapReduce cuando queremos afrontar problemas relacionados con grandes, enormes cantidades de datos. Y es por eso que se considera que debe correr en un sistema de archivos distribuidos, como es el caso de HDFS (Hadoop Distributed File System).</p>
<p>Si bien MapReduce es una propuesta para paralizar y distribuir el cómputo sobre grandes cantidades de datos, tenemos que tener en cuenta que no todos los problemas son susceptibles de afrontarse usándolo, y tampoco es una solución buena para trabajos que requieren de respuesta en tiempo real, MapReduce es más bien para procesamiento offline de información.</p>
</description>
<pubDate>Mon, 19 Feb 2018 18:00:00 +0000</pubDate>
<link>http://thatcsharpguy.com/tv/mapreduce/</link>
<guid isPermaLink="true">http://thatcsharpguy.com/tv/mapreduce/</guid>
<category>Meta</category>
<category>Tv</category>
<category>tv</category>
</item>
<item>
<title>Python</title>
<description><h1 id="python">Python.</h1>
<p>Como muchos de ustedes ya sabrán, Python es un lenguaje de programación, que como muy pocos seguramente saben, tomó su nombre no de una serpiente, si no de un programa de comedia británico, pero en fin. Python fue publicado en 1991 por Guido van Rossum, inicialmente fue pensado como un simple lenguaje de scripting pero en la actualidad se ha infiltrado en el desarrollo web, la ciencia de datos, machine learning y ramas afines.</p>
<h2 id="filosofía">Filosofía.</h2>
<p>La filosofía detrás de Python podría estar resumida en un documento que fue creado en 1999, ocho años después de su creación. Pueden consultar el documento en este enlace: pero les voy a decir algunos de estos principios que sí, suenan muy filosóficos:</p>
<ul>
<li>Beautiful is better than ugly</li>
<li>Explicit is better than implicit</li>
<li>Simple is better than complex</li>
<li>Readability counts</li>
<li>There should be one—and preferably only one—obvious way to do it.</li>
<li>If the implementation is hard to explain, it’s a bad idea.</li>
</ul>
<p>Lo cierto es que mientras que estos principios suenan bonitos, el escribir software todavía recae en los humanos, así que estos principios no se aplican muchas veces. Y, por ejemplo, puedes encontrar que en Python es normal que encuentres más de una manera de hacer las cosas.</p>
<h2 id="características">Características</h2>
<ul>
<li><strong>Es dinámicamente tipado</strong>: Porque podemos hacer algo como esto:</li>
</ul>
<pre><code>a = 1
b = 'C'
c = [0.1, 0.5]
</code></pre>
<p>Es decir, no es necesario especificar el tipo de dato de una variable antes de declararla. Y no existe un compilador, ni el intérprete, que esté comprobando esto antes de que el programa se esté ejecutando.</p>
<p>También permite algo como esto:</p>
<pre><code>a = 1
a = 'C'
a = [0.1, 0.5]
</code></pre>
<p>Es decir, cambiar por completo el tipo de dato de una variable sin que nadie diga nada. Y créanme, esto puede ser motivo de muchas confusiones, pero una vez que te acostumbras, puede llegar a ser una herramienta muy útil.</p>
<ul>
<li>sin embargo, también es considerado un lenguaje <strong>fuertemente tipado</strong> (cabe recalcar que puede existir esta combinación: dinámico y fuertemente tipado a la vez). Es considerado fuertemente tipado porque el lenguaje define un conjunto de reglas (de comportamientos) bajo las cuales los tipos de dato se pueden mezclar entre ellos, y romper esas reglas generará una excepción. Toma por ejemplo el siguiente código:</li>
</ul>
<pre><code>a3 = "a" + 3
</code></pre>
<p>por increíble que parezca, esto nos generaría un error puesto que los tipos de dato int y string no definen una forma de mezclarse, si quieres concatenar las cadenas tendrías que primero convertir el entero a cadena.</p>
<ul>
<li><strong>No existen los corchetes (o llaves)</strong>: sino que los bloques de código se definen usando indentaciones, es decir un bloque <code>if</code> se define de la siguiente manera:</li>
</ul>
<pre><code>if b == 'C':
print("b es C")
elif b == 'A':
print("b es A")
</code></pre>
<p>O un código un poco más complejo se vería así:</p>
<pre><code>def del_none(d):
for key, value in list(d.items()):
if value is None:
del d[key]
elif isinstance(value, str):
d[key] = d[key].strip()
elif isinstance(value, dict):
del_none(value)
return d
</code></pre>
<p>Ah, seguramente lo notaste, pero Python tampoco requiere que uses un <code>;</code> para terminar cada instrucción, la idea es que exista una instrucción por cada línea.</p>
<ul>
<li>como tal vez pudiste ver, es también un <strong>lenguaje de alto nivel</strong>: La idea es abstraer (esconder) la mayor cantidad de detalles de implementación. Es un lenguaje de alto nivel y en ocasiones es muy sencillo leer programas escritos en este lenguaje, y a mi parecer, en muchos casos como si estuvieras leyendo un libro escrito en inglés.</li>
<li>Python es también <strong>multiparadigma</strong>, puedes organizar tu código en clases, o utilizarlo como un lenguaje funcional, o puedes simplemente crear un programa que se ejecute proceduralmente… o una combinación de todo esto.</li>
<li><strong>Altamente extensible</strong>: tiene soporte para descargar módulos o bibliotecas de repositorios de paquetes que permiten que añadirle funcionalidad a tus programas, así que es normal que cuando descargues un proyecto tengas que descargar los paquetes asociados con instrucciones como las siguientes:</li>
</ul>
<pre><code>pip install package-name
easy_install package-name
</code></pre>
<h2 id="desventajas">Desventajas</h2>
<ul>
<li>Considerado <strong>lento</strong></li>
<li>A pesar de ser muy usado, hay áreas en las que no tiene mucho impacto, como el desarrollo para móviles.</li>
<li>Consume mucha memoria.</li>
<li>Puede hacer que otros lenguajes sean difíciles de trabajar, uno se acostumbra muy rápido a las bondades de Python, a mi de pronto ya se me olvida poner puntos y coma en C#</li>
</ul>
</description>
<pubDate>Mon, 05 Feb 2018 18:00:00 +0000</pubDate>
<link>http://thatcsharpguy.com/tv/python/</link>
<guid isPermaLink="true">http://thatcsharpguy.com/tv/python/</guid>
<category>Meta</category>
<category>Tv</category>
<category>tv</category>
</item>
<item>
<title>¿Dormir o programar?</title>
<description><p>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.</p>
<p>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.</p>
<p>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:</p>
<ul>
<li>Estás de mal humor,</li>
<li>te duele la cabeza,</li>
<li>no te dan muchas ganas de hablar con nadie,</li>
<li>te sientes desanimado y sin creatividad,</li>
<li>y te resulta imposible concentrarte…</li>
<li>¡además de que te andas quedando dormido en todos lados!</li>
</ul>
<p>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?</p>
<p>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.</p>
<p>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.</p>
<p>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í.</p>
<p>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.</p>
</description>
<pubDate>Sat, 27 Jan 2018 18:00:00 +0000</pubDate>
<link>http://thatcsharpguy.com/tv/dormir-programar/</link>
<guid isPermaLink="true">http://thatcsharpguy.com/tv/dormir-programar/</guid>
<category>Meta</category>
<category>Tv</category>
<category>tv</category>
</item>
</channel>
</rss>