<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chun Fei Lung</title>
    <description>The latest articles on DEV Community by Chun Fei Lung (@chuniversiteit).</description>
    <link>https://dev.to/chuniversiteit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F347027%2F9eee7e34-45ec-45c1-b1db-463c1d1bfab4.png</url>
      <title>DEV Community: Chun Fei Lung</title>
      <link>https://dev.to/chuniversiteit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chuniversiteit"/>
    <language>en</language>
    <item>
      <title>You should be able to turn off your camera in virtual meetings</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Wed, 29 Sep 2021 20:31:31 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/you-should-be-able-to-turn-off-your-camera-in-virtual-meetings-4pom</link>
      <guid>https://dev.to/chuniversiteit/you-should-be-able-to-turn-off-your-camera-in-virtual-meetings-4pom</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Turn off that camera!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I read and summarise software engineering papers for fun, and today we’re having a look at &lt;a href="https://doi.org/10.1037/apl0000948" rel="noopener noreferrer"&gt;The fatiguing effects of camera use in virtual meetings: A within-person field experiment&lt;/a&gt; (2021) by Shockley et al.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Earlier this year I posted &lt;a href="https://chuniversiteit.nl/papers/remote-onboarding-of-software-developers" rel="noopener noreferrer"&gt;a summary of “Please turn your cameras on: Remote onboarding of software developers during a pandemic”&lt;/a&gt;, which included the following suggestion:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Team members should turn their cameras on during video calls, as this makes it easier for new hires to understand the dynamics of the team, and helps them bond and form connections with their team members.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think this is good advice. But you may want to turn them off again once everyone has settled in…&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtual meeting fatigue
&lt;/h2&gt;

&lt;p&gt;During 2020 many organisations were forced to transition from office work to remote work in an attempt to reduce the spread of COVID-19. Face-to-face meetings were replaced by video calls and lengthy commutes briefly became a thing of the past.&lt;/p&gt;

&lt;p&gt;But workdays didn’t become less exhausting. It didn’t take very long before workers noticed that something called “Zoom fatigue” or “virtual meeting fatigue” was what made their days so exhausting, especially after a day filled with virtual meetings.&lt;/p&gt;

&lt;p&gt;It’s not entirely clear what causes virtual meeting fatigue. While the number of meetings increased during the pandemic, the overall &lt;a href="http://www.nber.org/papers/w27612" rel="noopener noreferrer"&gt;time spent in meetings was actually &lt;em&gt;reduced&lt;/em&gt; by 11.5%&lt;/a&gt;. This is why some scholars suspected that other properties of virtual meetings, like camera usage, might be the cause of this mysterious fatigue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why point the finger at the camera?
&lt;/h2&gt;

&lt;p&gt;The reason why scholars think that camera usage may be the culprit has to do with &lt;strong&gt;self-representation&lt;/strong&gt;; the idea that people want to be viewed positively by others and thus behave in ways that make them look good.&lt;/p&gt;

&lt;p&gt;Self-representation plays an important role in social exchanges, in the form of unwritten social cues. Taking care to present yourself in a positive light has practical career benefits, but also comes at a cost: it’s cognitively demanding.&lt;/p&gt;

&lt;p&gt;There are several reasons why virtual meetings could be more demanding than face-to-face ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Most popular virtual meeting platforms show all participants in a grid layout that gives each participant the feeling that they are constantly being watched by all other participants.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Virtual meeting software also tends to show you your own video image, which makes you more aware of the fact that others can see (and possibly silently judge) you.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users constantly receive nonverbal cues that are hard to interpret, e.g. because you can’t really tell what someone is looking at. They generally try to compensate for this by sending extra intentional cues (e.g. nodding exaggeratedly), which also requires more cognitive effort.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Self-representation is costly, but it’s costlier for some than for others:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Because &lt;strong&gt;women&lt;/strong&gt; tend to have lower statuses, are judged more harshly and are held against higher grooming standards than men, they feel pressured to invest more effort into self-representation than men;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;New employees&lt;/strong&gt; still need to “earn” their reputation and thus have a stronger need to maintain a professional appearance, whereas older employees can kind of do whatever they want because people already know they are qualified.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The authors hypothesise that self-representation leads to fatigue, which might cause employees to perform less effectively. The authors are specifically interested  in two specific indicators:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;the ability to &lt;strong&gt;voice&lt;/strong&gt; ideas and&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the ability to stay &lt;strong&gt;engaged&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testing the effect of camera usage
&lt;/h2&gt;

&lt;p&gt;The authors of the paper conducted a 4-week study with 103 participants at BroadPath, a US company within the healthcare sector that employs several thousand remote workers throughout the United States. About half of all participants were in managerial roles, although at least some also seem to have more technical roles in IT and software development.&lt;/p&gt;

&lt;p&gt;Half of the participants were asked to keep their camera off for the first two weeks and to turn it on for the last two weeks. Conversely, the other half made sure it was on for the first two weeks and kept it off for the last two. All participants also completed a daily survey that asked them how they felt about their workday.&lt;/p&gt;

&lt;h2&gt;
  
  
  Please turn your cameras off?
&lt;/h2&gt;

&lt;p&gt;The authors found that camera usage is indeed positively related to fatigue. The assumptions that self-representation is more costly for women and new employees also seem to be correct.&lt;/p&gt;

&lt;p&gt;This cannot be said for the hours spent in virtual meetings and the number of virtual meetings, which aren’t correlated with fatigue.&lt;/p&gt;

&lt;p&gt;With regard to the hypothesised effects of fatigue, the results suggest that camera use has a negative effect on voice and engagement. However, the measured effect is indirect, so this result should be taken with a grain of salt.&lt;/p&gt;

&lt;p&gt;Combined, the results suggest that camera usage is particularly fatiguing for women and newer employees and disproportionately hurts their ability to participate in meetings effectively.&lt;/p&gt;

&lt;p&gt;Does this mean that cameras should always be turned off in virtual meetings? Not necessarily, but it’s good to at least give people the option to turn off their camera. &lt;a href="https://doi.org/10.1016/j.resconrec.2020.105389" rel="noopener noreferrer"&gt;It would also be more environmentally friendly.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This study also didn’t look at the effect that camera usage has on &lt;em&gt;other&lt;/em&gt; participants, which you might want to consider as well.&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>meetings</category>
      <category>office</category>
    </item>
    <item>
      <title>A comparison of libraries for named entity recognition</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Mon, 27 Sep 2021 10:52:10 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/a-comparison-of-libraries-for-named-entity-recognition-5583</link>
      <guid>https://dev.to/chuniversiteit/a-comparison-of-libraries-for-named-entity-recognition-5583</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What’s your favourite thing about SpaCy? Mine’s SpaCy.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I read and summarise software engineering papers for fun, and today we’re having a look at &lt;a href="https://doi.org/10.1145/3191697.3214341" rel="noopener noreferrer"&gt;A replicable comparison study of NER software: StanfordNLP, NLTK, OpenNLP, SpaCy, GATE&lt;/a&gt; (2019) by Schmitt et al.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Natural_language_processing" rel="noopener noreferrer"&gt;Natural language processing&lt;/a&gt; (NLP) is a subfield of artificial intelligence that is dedicated to the understanding, processing, and generation of natural languages, like French and English.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Named-entity_recognition" rel="noopener noreferrer"&gt;Named entity recognition&lt;/a&gt; (NER) is a subtask of NLP that aims to identify entities (persons, locations) in texts. This can be used for things like machine translation, automated question answering, and automated text summarisation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;If you need NER, there’s no need to implement it yourself. There are several popular libraries that can do this for you nowadays. Five of these libraries, &lt;a href="https://stanfordnlp.github.io/CoreNLP/" rel="noopener noreferrer"&gt;Stanford CoreNLP&lt;/a&gt;, &lt;a href="https://www.nltk.org/" rel="noopener noreferrer"&gt;NLTK&lt;/a&gt;, &lt;a href="https://opennlp.apache.org/" rel="noopener noreferrer"&gt;OpenNLP&lt;/a&gt;, &lt;a href="https://spacy.io/" rel="noopener noreferrer"&gt;SpaCy&lt;/a&gt;, and &lt;a href="https://gate.ac.uk/" rel="noopener noreferrer"&gt;GATE&lt;/a&gt;, were already mentioned in the title.&lt;/p&gt;

&lt;p&gt;Which library is right for you depends on various criteria, like its performance, cost, documentation, license, and the programming language in which it is implemented.&lt;/p&gt;

&lt;p&gt;Many of these libraries have been evaluated in comparison studies, but sadly not in a way that makes it easy to compare findings.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the study was conducted
&lt;/h2&gt;

&lt;p&gt;This paper describes a comparison between the five aforementioned NER libraries, in a sufficiently clear and complete way, so that its results can be replicated.&lt;/p&gt;

&lt;p&gt;The process looks roughly like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Selection of two corpora that are not domain-specific, freely available, and in English: the &lt;a href="https://gmb.let.rug.nl/" rel="noopener noreferrer"&gt;Groningen Meaning Bank&lt;/a&gt; (GMB) and the &lt;a href="https://www.aclweb.org/anthology/W03-0419.pdf" rel="noopener noreferrer"&gt;CoNLL 2003 corpus&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Selection of five NER libraries that are free and open-source software, well-documented, available for Linux, and can recognise at least three types of entities: persons, organisations, and locations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Comparison of each NER library’s generated NER annotations with annotations in the “gold data”, which contains the annotations that we’d expect. This is done by computing the precision, recall, and F-score for each library.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What discoveries were made
&lt;/h2&gt;

&lt;p&gt;The table below shows the results of the comparison. Don’t worry too much about its size and all the numbers, I’ve included a hangover-proof summary below the table.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;td colspan="2"&gt;&lt;/td&gt;
      &lt;th colspan="3"&gt;CoNLL 2003&lt;/th&gt;
      &lt;th colspan="3"&gt;GMB&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Library&lt;/th&gt;
      &lt;th&gt;Entity&lt;/th&gt;
      &lt;th&gt;Precision&lt;/th&gt;
      &lt;th&gt;Recall&lt;/th&gt;
      &lt;th&gt;F-score&lt;/th&gt;
      &lt;th&gt;Precision&lt;/th&gt;
      &lt;th&gt;Recall&lt;/th&gt;
      &lt;th&gt;F-score&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th rowspan="4"&gt;Stanford NLP&lt;/th&gt;
      &lt;td&gt;Location&lt;/td&gt;
      &lt;td&gt;91.30&lt;/td&gt;
      &lt;td&gt;88.73&lt;/td&gt;
      &lt;td&gt;90.00&lt;/td&gt;
      &lt;td&gt;83.10&lt;/td&gt;
      &lt;td&gt;63.64&lt;/td&gt;
      &lt;td&gt;72.08&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Organisation&lt;/td&gt;
      &lt;td&gt;86.32&lt;/td&gt;
      &lt;td&gt;80.92&lt;/td&gt;
      &lt;td&gt;83.53&lt;/td&gt;
      &lt;td&gt;71.40&lt;/td&gt;
      &lt;td&gt;47.42&lt;/td&gt;
      &lt;td&gt;56.99&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Person&lt;/td&gt;
      &lt;td&gt;92.72&lt;/td&gt;
      &lt;td&gt;82.68&lt;/td&gt;
      &lt;td&gt;87.41&lt;/td&gt;
      &lt;td&gt;78.59&lt;/td&gt;
      &lt;td&gt;84.70&lt;/td&gt;
      &lt;td&gt;81.53&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Overall&lt;/td&gt;
      &lt;td&gt;90.06&lt;/td&gt;
      &lt;td&gt;73.67&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;81.05&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;79.81&lt;/td&gt;
      &lt;td&gt;63.74&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;70.88&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th rowspan="4"&gt;NLTK&lt;/th&gt;
      &lt;td&gt;Location&lt;/td&gt;
      &lt;td&gt;52.47&lt;/td&gt;
      &lt;td&gt;65.47&lt;/td&gt;
      &lt;td&gt;58.26&lt;/td&gt;
      &lt;td&gt;77.13&lt;/td&gt;
      &lt;td&gt;77.10&lt;/td&gt;
      &lt;td&gt;77.12&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Organisation&lt;/td&gt;
      &lt;td&gt;36.20&lt;/td&gt;
      &lt;td&gt;24.80&lt;/td&gt;
      &lt;td&gt;29.44&lt;/td&gt;
      &lt;td&gt;42.06&lt;/td&gt;
      &lt;td&gt;35.54&lt;/td&gt;
      &lt;td&gt;38.53&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Person&lt;/td&gt;
      &lt;td&gt;61.09&lt;/td&gt;
      &lt;td&gt;66.11&lt;/td&gt;
      &lt;td&gt;63.50&lt;/td&gt;
      &lt;td&gt;38.07&lt;/td&gt;
      &lt;td&gt;55.87&lt;/td&gt;
      &lt;td&gt;45.28&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Overall&lt;/td&gt;
      &lt;td&gt;51.78&lt;/td&gt;
      &lt;td&gt;45.56&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;48.47&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;60.96&lt;/td&gt;
      &lt;td&gt;63.91&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;62.40&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th rowspan="4"&gt;GATE&lt;/th&gt;
      &lt;td&gt;Location&lt;/td&gt;
      &lt;td&gt;59.63&lt;/td&gt;
      &lt;td&gt;78.63&lt;/td&gt;
      &lt;td&gt;67.82&lt;/td&gt;
      &lt;td&gt;79.03&lt;/td&gt;
      &lt;td&gt;48.16&lt;/td&gt;
      &lt;td&gt;59.85&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Organisation&lt;/td&gt;
      &lt;td&gt;50.58&lt;/td&gt;
      &lt;td&gt;21.29&lt;/td&gt;
      &lt;td&gt;29.96&lt;/td&gt;
      &lt;td&gt;45.08&lt;/td&gt;
      &lt;td&gt;37.68&lt;/td&gt;
      &lt;td&gt;41.05&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Person&lt;/td&gt;
      &lt;td&gt;69.53&lt;/td&gt;
      &lt;td&gt;62.67&lt;/td&gt;
      &lt;td&gt;65.92&lt;/td&gt;
      &lt;td&gt;46.53&lt;/td&gt;
      &lt;td&gt;53.70&lt;/td&gt;
      &lt;td&gt;49.86&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Overall&lt;/td&gt;
      &lt;td&gt;61.48&lt;/td&gt;
      &lt;td&gt;47.44&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;53.55&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;61.72&lt;/td&gt;
      &lt;td&gt;46.78&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;53.22&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th rowspan="4"&gt;OpenNLP&lt;/th&gt;
      &lt;td&gt;Location&lt;/td&gt;
      &lt;td&gt;76.54&lt;/td&gt;
      &lt;td&gt;52.22&lt;/td&gt;
      &lt;td&gt;62.08&lt;/td&gt;
      &lt;td&gt;84.34&lt;/td&gt;
      &lt;td&gt;45.84&lt;/td&gt;
      &lt;td&gt;59.40&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Organisation&lt;/td&gt;
      &lt;td&gt;38.06&lt;/td&gt;
      &lt;td&gt;14.87&lt;/td&gt;
      &lt;td&gt;21.39&lt;/td&gt;
      &lt;td&gt;59.27&lt;/td&gt;
      &lt;td&gt;30.64&lt;/td&gt;
      &lt;td&gt;40.39&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Person&lt;/td&gt;
      &lt;td&gt;83.94&lt;/td&gt;
      &lt;td&gt;37.17&lt;/td&gt;
      &lt;td&gt;51.52&lt;/td&gt;
      &lt;td&gt;62.34&lt;/td&gt;
      &lt;td&gt;41.98&lt;/td&gt;
      &lt;td&gt;50.17&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Overall&lt;/td&gt;
      &lt;td&gt;68.68&lt;/td&gt;
      &lt;td&gt;30.44&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;42.18&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;37.35&lt;/td&gt;
      &lt;td&gt;41.71&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;39.41&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th rowspan="4"&gt;SpaCy&lt;/th&gt;
      &lt;td&gt;Location&lt;/td&gt;
      &lt;td&gt;73.38&lt;/td&gt;
      &lt;td&gt;75.36&lt;/td&gt;
      &lt;td&gt;74.36&lt;/td&gt;
      &lt;td&gt;77.04&lt;/td&gt;
      &lt;td&gt;56.64&lt;/td&gt;
      &lt;td&gt;65.28&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Organisation&lt;/td&gt;
      &lt;td&gt;40.95&lt;/td&gt;
      &lt;td&gt;36.24&lt;/td&gt;
      &lt;td&gt;38.45&lt;/td&gt;
      &lt;td&gt;41.20&lt;/td&gt;
      &lt;td&gt;36.50&lt;/td&gt;
      &lt;td&gt;38.70&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Person&lt;/td&gt;
      &lt;td&gt;66.89&lt;/td&gt;
      &lt;td&gt;56.22&lt;/td&gt;
      &lt;td&gt;61.09&lt;/td&gt;
      &lt;td&gt;67.41&lt;/td&gt;
      &lt;td&gt;69.14&lt;/td&gt;
      &lt;td&gt;68.27&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Overall&lt;/td&gt;
      &lt;td&gt;60.94&lt;/td&gt;
      &lt;td&gt;49.01&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;54.33&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;66.15&lt;/td&gt;
      &lt;td&gt;54.32&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;59.66&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Stanford NLP’s library is the only one that has (somewhat) high scores and blows the other libraries out of the water. The other four libraries have a roughly similar level of performance.&lt;/p&gt;

&lt;p&gt;Note that Stanford NLP’s library performs especially well on the CoNLL 2003 dataset. This is because it comes with a classifier that was partially trained on CoNLL 2003! The scores for GMB are therefore more likely to be representative for real-world texts.&lt;/p&gt;

&lt;p&gt;The results for Stanford NLP are similar to those from other studies. However, the accuracy for three of the other libraries (NLTK, GATE, and OpenNLP) (*) may differ as much as 66% from the values reported in existing studies. It is not clear what causes such huge discrepancies.&lt;/p&gt;

&lt;p&gt;(*) &lt;em&gt;Apparently there weren’t any studies that evaluated SpaCy’s performance&lt;/em&gt;&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>python</category>
      <category>java</category>
      <category>programming</category>
    </item>
    <item>
      <title>How do you hide low-quality tweets from Twitter searches?</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Mon, 20 Sep 2021 15:02:42 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/how-do-you-hide-low-quality-tweets-from-twitter-searches-2006</link>
      <guid>https://dev.to/chuniversiteit/how-do-you-hide-low-quality-tweets-from-twitter-searches-2006</guid>
      <description>&lt;p&gt;I created my current Twitter account in 2009. Back then, the service was still relatively new and no one really knew what to use it for. Consequently nearly all of the “content” produced by individuals was crap: most people probably used it to share dumb status updates about literally everything, as if they were trying to implement some sort of digital real-life version of event sourcing.&lt;/p&gt;

&lt;p&gt;Things have improved a lot since then. There’s a lot more interesting content on Twitter, &lt;a href="https://chuniversiteit.nl/papers/need-for-tweet" rel="noopener noreferrer"&gt;especially for developers&lt;/a&gt;… provided that you can find it.&lt;/p&gt;

&lt;p&gt;You can follow individual accounts or lists that have been created by other users of course. Or you could subscribe to certain topics of interest.&lt;/p&gt;

&lt;p&gt;Tweets about specific things made by casual users (whose tweets have very few likes and retweets) can be found using Twitter’s search functionality. It works for the most part. But it sorely lacks an easy way to filter out (what I think are) uninteresting tweets.&lt;/p&gt;

&lt;p&gt;Because everyone probably has their own preferences and definitions of “good” and “bad” tweets, here’s what &lt;em&gt;I&lt;/em&gt; mean by uninteresting tweets.&lt;/p&gt;

&lt;p&gt;Tweets that only show up in search results because they contain &lt;a href="https://en.wikipedia.org/wiki/Keyword_stuffing" rel="noopener noreferrer"&gt;an obscene number of hashtags&lt;/a&gt; that aren’t relevant at all:&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1438971371963432961-448" src="https://platform.twitter.com/embed/Tweet.html?id=1438971371963432961"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1438971371963432961-448');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1438971371963432961&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;As far as I know, there’s no easy way to filter out tweets that contain more hashtags than actual content.&lt;/p&gt;

&lt;p&gt;Keywords don’t have to be hashtags however. Most people who regularly search for tweets about a popular programming language will likely have seen something like this:&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1438971177754578945-214" src="https://platform.twitter.com/embed/Tweet.html?id=1438971177754578945"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1438971177754578945-214');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1438971177754578945&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;It gets worse when a programming language uses a fairly generic name that has other more common meanings, like PHP.&lt;/p&gt;

&lt;p&gt;I wish there was an easy way to filter out accounts from the Philippines (especially those with Korean avatars 😅), as its currency is also abbreviated using PHP:&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1438950117185228800-626" src="https://platform.twitter.com/embed/Tweet.html?id=1438950117185228800"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1438950117185228800-626');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1438950117185228800&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;While you can filter by tweet location, it doesn’t seem possible to &lt;em&gt;exclude&lt;/em&gt; locations. Also, very few tweets actually have location data.&lt;/p&gt;

&lt;p&gt;Then there are also very personal tweets about partial hospitalisation programmes (also PHP) for patients with mental illnesses. I’m not providing an example of such a tweet here for reasons that should be fairly obvious…&lt;/p&gt;

&lt;p&gt;PHP is far from the only language or concept that has this problem. &lt;code&gt;java&lt;/code&gt;, &lt;code&gt;go&lt;/code&gt;, &lt;code&gt;nlp&lt;/code&gt;, and (to a lesser extent) &lt;code&gt;python&lt;/code&gt; also have other, more common uses.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I (try to) filter out bad tweets
&lt;/h2&gt;

&lt;p&gt;I mostly use Twitter’s search for personal (rather than commercial or professional) reasons. I therefore simply “subscribe” to search queries using Twitter’s own freely available &lt;a href="https://tweetdeck.twitter.com/" rel="noopener noreferrer"&gt;TweetDeck&lt;/a&gt; web app.&lt;/p&gt;

&lt;p&gt;My queries usually look like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I start with the keywords that I’m interested in.&lt;/li&gt;
&lt;li&gt;I append a &lt;code&gt;lang:en&lt;/code&gt; so that &lt;em&gt;most&lt;/em&gt; of the search results will be in English&lt;/li&gt;
&lt;li&gt;Virtually all advertisements will include links, which I sometimes (but not always) remove from my results using &lt;code&gt;-filter:links&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Because there are no easy ways to filter out spam, I then add a list of words that I want to exclude:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Keyword&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;hxxps&lt;/td&gt;
&lt;td&gt;(Automated?) tweets about security vulnerabilities on specific URLs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;threat&lt;/td&gt;
&lt;td&gt;(Automated?) tweets about security vulnerabilities on specific URLs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hiring&lt;/td&gt;
&lt;td&gt;Recruitment ads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;jobs&lt;/td&gt;
&lt;td&gt;Recruitment ads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;remote&lt;/td&gt;
&lt;td&gt;Recruitment ads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;talent&lt;/td&gt;
&lt;td&gt;Recruitment ads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;talents&lt;/td&gt;
&lt;td&gt;Recruitment ads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vacancies&lt;/td&gt;
&lt;td&gt;Recruitment ads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vacancy&lt;/td&gt;
&lt;td&gt;Recruitment ads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;retweet&lt;/td&gt;
&lt;td&gt;Promotional tweet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rt&lt;/td&gt;
&lt;td&gt;Promotional tweet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;blockchain&lt;/td&gt;
&lt;td&gt;Keyword stuffing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;coinbase&lt;/td&gt;
&lt;td&gt;Keyword stuffing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;crypto&lt;/td&gt;
&lt;td&gt;Keyword stuffing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cryptocurrency&lt;/td&gt;
&lt;td&gt;Keyword stuffing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;digitalmarketing&lt;/td&gt;
&lt;td&gt;Keyword stuffing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iot&lt;/td&gt;
&lt;td&gt;Keyword stuffing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ml&lt;/td&gt;
&lt;td&gt;Keyword stuffing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nft&lt;/td&gt;
&lt;td&gt;Keyword stuffing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pytorch&lt;/td&gt;
&lt;td&gt;Keyword stuffing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;anatomy&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;assignment&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;biology&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;chemistry&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;course&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;essay&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;essayhelp&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;essaypay&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;essays&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;essaysdue&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;exam&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;exams&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;grade&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;grades&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;homework&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;paper&lt;/td&gt;
&lt;td&gt;Homework/thesis services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;codingpics&lt;/td&gt;
&lt;td&gt;Low-quality tweets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;meme&lt;/td&gt;
&lt;td&gt;Low-quality tweets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;programmingjoke&lt;/td&gt;
&lt;td&gt;Low-quality tweets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;programmingjokes&lt;/td&gt;
&lt;td&gt;Low-quality tweets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;programmingmemes&lt;/td&gt;
&lt;td&gt;Low-quality tweets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;doctor&lt;/td&gt;
&lt;td&gt;Is likely about hospitalisation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hospital&lt;/td&gt;
&lt;td&gt;Is likely about hospitalisation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;album&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;buy&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;buyer&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cost&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;costs&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;currency&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;deal&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;discounted&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dm&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dropship&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dropshipping&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fashion&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fee&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;free&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gcash&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gift&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;items&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kpop&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;payment&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;paypal&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;peso&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pesos&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pm&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;price&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;prices&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rewards&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sale&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sales&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sell&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;shop&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sold&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;spend&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;unlock&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;usd&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wts&lt;/td&gt;
&lt;td&gt;People trying to sell stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"how much"&lt;/td&gt;
&lt;td&gt;People trying to buy stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wtb&lt;/td&gt;
&lt;td&gt;People trying to buy stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As you can see the list is pretty long. This means that there are inevitably going to be interesting tweets that I never see because they are excluded by my queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about you?
&lt;/h2&gt;

&lt;p&gt;This approach &lt;em&gt;mostly&lt;/em&gt; works for me, but I have the feeling there are much better ways to do this.&lt;/p&gt;

&lt;p&gt;How do you separate the (t)wheat from the chaff? Do you use extensions? Alternative Twitter clients? Share your strategies in the comments!&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>twitter</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Can Java and C++ devs write better Python code than Python devs?</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Tue, 14 Sep 2021 10:37:35 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/can-java-and-c-devs-write-better-python-code-than-python-devs-57i6</link>
      <guid>https://dev.to/chuniversiteit/can-java-and-c-devs-write-better-python-code-than-python-devs-57i6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Each person has their own, unique style&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I read and summarise software engineering papers for fun, and today we’re having a look at &lt;a href="https://doi.org/10.1145/3191697.3214341" rel="noopener noreferrer"&gt;Do Java developers write better Python? Studying off-language code quality on GitHub&lt;/a&gt; (2018) by Horschig, Mattis, and Hirschfeld.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Things can often be coded in different ways. For instance, you can use different algorithms, &lt;a href="https://chuniversiteit.nl/papers/on-using-and-naming-intermediate-variables" rel="noopener noreferrer"&gt;use fewer or more lines of code&lt;/a&gt;, implement functionality using different libraries or frameworks, or use a certain code style.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;Most programming language communities have &lt;a href="https://chuniversiteit.nl/papers/on-the-usage-of-pythonic-idioms" rel="noopener noreferrer"&gt;coding conventions&lt;/a&gt;. These conventions ensure that code written by different people looks similar. This can make code more readable, less prone to errors, and more maintainable.&lt;/p&gt;

&lt;p&gt;Spend enough time with a language, and you will eventually be able to apply all of a language’s conventions effortlessly.&lt;/p&gt;

&lt;p&gt;However, each language has its own coding conventions (*). So what happens when you switch to a different language? You might write code that’s less maintainable or more prone to errors. Or maybe you’re actually able to write &lt;em&gt;better&lt;/em&gt; code, because your new language has fewer (or worse) conventions.&lt;/p&gt;

&lt;p&gt;(*) &lt;em&gt;And in some cases there are actually multiple sets of conventions!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Well, let’s find out what happens!&lt;/p&gt;

&lt;h2&gt;
  
  
  How the study was conducted
&lt;/h2&gt;

&lt;p&gt;A very large part of today’s open source development happens on &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. GitHub provides an API that can be used to retrieve data about its platform, but there is (or was) also a &lt;a href="https://ghtorrent.org/" rel="noopener noreferrer"&gt;GHTorrent project&lt;/a&gt; that mirrored GitHub’s (public parts of) repositories, user profiles, commits, issues, and other artifacts.&lt;/p&gt;

&lt;p&gt;The researchers used the latter to look for developers who have made a large number of contributions in their primary language, and a much smaller number in some secondary language. We can treat these developers as the experimental group. We also need a control group; that one consists of users that only contributed using one programming language.&lt;/p&gt;

&lt;p&gt;Then, the researchers mined the dataset for projects that were edited by developers using their secondary language.&lt;/p&gt;

&lt;p&gt;For this study, they looked at Python projects that were edited by Java and C++ developers. These are compared to Python projects that were only edited by Python developers.&lt;/p&gt;

&lt;p&gt;To study the effect of language switching, all projects were analysed using &lt;a href="https://www.pylint.org/" rel="noopener noreferrer"&gt;Pylint&lt;/a&gt;, which can find various types of issues in Python code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;fatal&lt;/strong&gt; errors that result in code that doesn’t work at all;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;errors&lt;/strong&gt; that cause runtime errors when the code is executed;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;warnings&lt;/strong&gt; for code that is error prone or has severe style issues;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;refactoring&lt;/strong&gt; hints for complex or messy code; and&lt;/li&gt;
&lt;li&gt;violations of coding &lt;strong&gt;conventions&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What discoveries were made
&lt;/h2&gt;

&lt;p&gt;The analysis ended up including data for 84 Java developers, 91 C++ developers, and 100 Python developers.&lt;/p&gt;

&lt;p&gt;The table below shows the differences in code quality per issue type (lower is better):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Code quality issue&lt;/th&gt;
      &lt;th&gt;Java group&lt;/th&gt;
      &lt;th&gt;C++ group&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;Line too long&lt;/th&gt;
      &lt;td&gt;3.59&lt;/td&gt;
      &lt;td&gt;1.44&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Invalid name&lt;/th&gt;
      &lt;td&gt;1.43&lt;/td&gt;
      &lt;td&gt;1.52&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Wrong import order&lt;/th&gt;
      &lt;td&gt;—&lt;/td&gt;
      &lt;td&gt;1.83&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Ungrouped imports&lt;/th&gt;
      &lt;td&gt;&lt;strong&gt;0.16&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;0.14&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Bad whitespace&lt;/th&gt;
      &lt;td&gt;—&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;0.38&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Unnecessary semicolon&lt;/th&gt;
      &lt;td&gt;4.42&lt;/td&gt;
      &lt;td&gt;20.62&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Redefining built-in names&lt;/th&gt;
      &lt;td&gt;&lt;strong&gt;0.57&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Bad indentation&lt;/th&gt;
      &lt;td&gt;3.39&lt;/td&gt;
      &lt;td&gt;3.28&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Redefining outer name&lt;/th&gt;
      &lt;td&gt;1.68&lt;/td&gt;
      &lt;td&gt;2.21&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Undefined loop variable&lt;/th&gt;
      &lt;td&gt;—&lt;/td&gt;
      &lt;td&gt;3.28&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Unused import&lt;/th&gt;
      &lt;td&gt;&lt;strong&gt;0.63&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;0.81&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Unused variable&lt;/th&gt;
      &lt;td&gt;1.56&lt;/td&gt;
      &lt;td&gt;2.25&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Complex method/function&lt;/th&gt;
      &lt;td&gt;&lt;strong&gt;0.84&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;1.48&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Too many public methods&lt;/th&gt;
      &lt;td&gt;&lt;strong&gt;0.26&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;0.46&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Too few public methods&lt;/th&gt;
      &lt;td&gt;&lt;strong&gt;0.34&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;0.58&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;No else return&lt;/th&gt;
      &lt;td&gt;—&lt;/td&gt;
      &lt;td&gt;1.52&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Undefined variable&lt;/th&gt;
      &lt;td&gt;—&lt;/td&gt;
      &lt;td&gt;1.55&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Assignment from no return&lt;/th&gt;
      &lt;td&gt;28.27&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What might be surprising is that Java/C++ developers sometimes write &lt;em&gt;better&lt;/em&gt; code than Python developers. The researchers provide the following explanations for each individual result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Line too long&lt;/strong&gt;: Python lines should not be longer than 80 characters. C++ and Java developers tend write lines that are longer than that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Invalid name&lt;/strong&gt;: Class names in Python should be CamelCased, while method and field names should be snake_cased. Programmers from the other two languages regularly violate these naming conventions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Wrong import order&lt;/strong&gt;: Module imports should be ordered such that standard libraries are imported first, followed by third-party libraries, and finally local imports. C++ developers violate this convention a lot more often, but Java developers seem to do the same thing as Python developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ungrouped imports&lt;/strong&gt;: Multiple imports from the same package should be grouped together. Java and C++ developers do this way more often than Python developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bad whitespace&lt;/strong&gt;: C++ and Java developers are less likely to miss or add too much whitespace around operators, brackets, and blocks than Python developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unnecessary semicolon&lt;/strong&gt;: Python doesn’t need semicolons at the end of lines, but (especially) C++ and Java developers tend to add them anyway.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Redefining built-in names&lt;/strong&gt;: Developers may accidentally use variable names which are already used for existing names (e.g. &lt;code&gt;input&lt;/code&gt; and &lt;code&gt;str&lt;/code&gt;). This may cause unexpected or confusing errors. Java developers do this &lt;em&gt;less often&lt;/em&gt; than Python developers, despite being less familiar with the language. This is probably because they use IDEs (which would point out such mistakes) rather than simple text editors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bad indentation&lt;/strong&gt;: Whitespace is important in Python, so it helps if tabs and spaces are used consistently. Java and C++ developers aren’t as good at this as Python developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Redefining outer name&lt;/strong&gt;: Shadowing names from outer scopes is discouraged in Python, but both Java and C++ developers do this more often than Python developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Undefined loop variable&lt;/strong&gt;: Using loop variables outside the loop can be useful in some situations, but only when the loop was actually executed. C++ developers are 3 times more likely to write code with potentially undefined variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unused import&lt;/strong&gt;: Both Java and C++ developers are less likely to have unused imports in their files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unused variable&lt;/strong&gt;: On the other hand, Java and C++ developers are &lt;em&gt;more&lt;/em&gt; likely to forget about previously defined variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Complex method/function&lt;/strong&gt;: C++ developers are more likely to write methods or functions with a cyclomatic complexity above 10.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Too many public methods&lt;/strong&gt;: Java and C++ developers tend to make smaller classes and thus don’t run into this issue as often.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Too few public methods&lt;/strong&gt;: The opposite, where classes are merely used as glorified data structures without any behaviour of their own, also occurs less often with Java and C++ developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No else return&lt;/strong&gt;: Having an &lt;code&gt;else&lt;/code&gt; statement after an &lt;code&gt;if&lt;/code&gt; is considered bad style. C++ developers use this more often than Python developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Undefined variable&lt;/strong&gt;: Undefined variables are often not reachable &lt;em&gt;right now&lt;/em&gt;, but might become reachable when the code is modified in the future and thus cause errors later. C++ developers are more likely to write code with undefined variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Assignment from no return&lt;/strong&gt;: Java developers are more likely to use “void” functions in assignments or as expressions, possibly because these would have been checked in Java during compilation – but not in Python.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>java</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Gender diversity makes teams communicate more effectively</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Thu, 09 Sep 2021 18:03:30 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/gender-diversity-makes-teams-communicate-more-effectively-1cap</link>
      <guid>https://dev.to/chuniversiteit/gender-diversity-makes-teams-communicate-more-effectively-1cap</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Software teams could use more women, but they aren’t lining up yet&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I read and summarise software engineering papers for fun, and today we’re having a look at &lt;a href="https://doi.org/10.1109/ICSE-SEIS.2019.00010" rel="noopener noreferrer"&gt;Gender diversity and women in software teams: How do they affect community smells?&lt;/a&gt; (2019) by Catolino et al.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Software development teams in western countries largely consist of males or are even male-only. Hiring policies that favour women over men can help restore the balance somewhat, but are also controversial. Do these policies actually make economical sense? Spoiler alert: yes, they do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;The key to good software development is good communication and collaboration between team members. Women tend to be better at these things, but most software teams don’t have even a single female member.&lt;/p&gt;

&lt;p&gt;Since communication is such an important part of software development, one might expect that teams with women are better equipped to avoid so-called “community smells” and thus outperform male-only teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the study was conducted
&lt;/h2&gt;

&lt;p&gt;The authors compared data about communication flows from 20 male-only open source projects with 20 open source projects from teams with at least one female member.&lt;/p&gt;

&lt;h2&gt;
  
  
  What discoveries were made
&lt;/h2&gt;

&lt;p&gt;Development teams without women indeed suffer from more community smells than teams that have any positive number of women – even if it’s just one. Given what we already know about social group dynamics this is hardly a surprise.&lt;/p&gt;

&lt;p&gt;There are many types of &lt;strong&gt;community smell&lt;/strong&gt;, but the authors chose to further analyse four types that are likely to be affected by the presence of women:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The community consists of multiple &lt;strong&gt;organisational siloes&lt;/strong&gt; that don’t communicate much with each other – and when they do, communication is handled by just one or two group members;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Community members are overwhelmed by a &lt;strong&gt;black cloud&lt;/strong&gt; of information due to a lack of structured communication;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are &lt;strong&gt;lone wolves&lt;/strong&gt; who work on their own and do not collaborate or communicate with others;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One member handles all communication across two or more subcommunities and thus results in &lt;strong&gt;radio silence&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The presence of women clearly affects whether the black clouds and radio silence smells (which are related to quality of communication) occur.&lt;/p&gt;

&lt;p&gt;It’s not as clear for the organisational silo and lone wolf smells (which have to do with organisational structure), as the authors only find a partial relation between gender diversity and the two smells.&lt;/p&gt;

&lt;p&gt;The results confirm that gender diversity in teams is a good thing to strive for and underlines the importance of team composition as a way to combat community smells.&lt;/p&gt;

</description>
      <category>inclusion</category>
      <category>communication</category>
    </item>
    <item>
      <title>Refactoring does not solve all problems… right away</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Mon, 06 Sep 2021 19:10:43 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/refactoring-does-not-solve-all-problems-right-away-2ba4</link>
      <guid>https://dev.to/chuniversiteit/refactoring-does-not-solve-all-problems-right-away-2ba4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Is it an improvement? I guess wheel never know with these uphill battles&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I read and summarise software engineering papers for fun, and today we’re having a look at &lt;a href="https://doi.org/10.1109/SANER.2015.7081865" rel="noopener noreferrer"&gt;Old habits die hard: Why refactoring for understandability does not give immediate benefits&lt;/a&gt; (2015) by Ammerlaan, Veninga, and Zaidman.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whenever shortcuts are taken during the development of a software system, it accumulates technical debt.&lt;/p&gt;

&lt;p&gt;This debt makes it harder to understand and make changes to the system, so the development speed for a system with a lot of technical debt will eventually come to a grinding halt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;Refactoring is a process where the structure of code is improved without changing the functionality of the system. Many in the software development community argue that well-structured code is easier to understand, and thus easier to modify and less prone to bugs.&lt;/p&gt;

&lt;p&gt;Unfortunately there is little empirical evidence that refactoring actually has beneficial effects on developer productivity. This study tries to shed some light on the matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the study was conducted
&lt;/h2&gt;

&lt;p&gt;A comparative experiment was conducted at Exact, a software company that produces business software with development teams that are distributed over multiple continents.&lt;/p&gt;

&lt;p&gt;The study consists of 5 different experiments and included 30 participants (all developers) from 11 different teams and two different countries (Malaysia and The Netherlands).&lt;/p&gt;

&lt;p&gt;In each experiment, a developer was asked to perform a small coding task on components from a codebase with 2.7 millions of lines of code: they either had to fix a small bug or make a small change in functionality. Participants in the experimental group were given a refactored version of the code, while those in the control group were given the original code.&lt;/p&gt;

&lt;p&gt;The experiment includes three types of refactorings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;small&lt;/strong&gt; &lt;em&gt;Rename&lt;/em&gt; &lt;a href="https://refactoring.com/catalog/renameField.html" rel="noopener noreferrer"&gt;&lt;em&gt;field&lt;/em&gt;&lt;/a&gt; or &lt;a href="https://refactoring.com/catalog/renameVariable.html" rel="noopener noreferrer"&gt;&lt;em&gt;variable&lt;/em&gt;&lt;/a&gt;, and &lt;a href="https://refactoring.com/catalog/extractFunction.html" rel="noopener noreferrer"&gt;&lt;em&gt;Extract function&lt;/em&gt;&lt;/a&gt; refactorings;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;medium&lt;/strong&gt; &lt;a href="https://refactoring.com/catalog/extractClass.html" rel="noopener noreferrer"&gt;&lt;em&gt;Extract class&lt;/em&gt;&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Adapter_pattern" rel="noopener noreferrer"&gt;&lt;em&gt;Adapter pattern&lt;/em&gt;&lt;/a&gt; refactorings, accompanied by one or more unit tests;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;large&lt;/strong&gt; refactorings to &lt;em&gt;divide responsibilities&lt;/em&gt;, also accompanied by unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What discoveries were made
&lt;/h2&gt;

&lt;p&gt;Results were mixed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

&lt;p&gt;In the first (small) experiment some helper methods were extracted from the code. Surprisingly, developers who saw the refactored version needed &lt;em&gt;more&lt;/em&gt; time to make the requested change, not less.&lt;/p&gt;

&lt;p&gt;The second (small) experiment had a similar setup, but was (apparently) easier to complete. This means that the productivity measurements for this experiment are less noisy. In this case, about 75% of the participants in the experimental group finished before 25% of the developers with the original code.&lt;/p&gt;

&lt;p&gt;The third (small) experiment again used similar refactorings and also resulted in lower finishing times for those who saw the original code without refactorings. It’s possible that flow of method arguments and return values between multiple smaller methods was harder to understand than a linear flow in a large method.&lt;/p&gt;

&lt;p&gt;In the fourth (medium) experiment participants were asked to fix a bug. It appears that those in the experimental group had slightly lower finishing times than those in the control group. Another notable finding is that developers who were quite experienced in unit testing performed better than other participants.&lt;/p&gt;

&lt;p&gt;In the fifth (large) experiment, developers who saw the original code once again did &lt;em&gt;much better&lt;/em&gt; than developers who had to work with the refactored code, presumably because it takes more time to understand the relations between classes that emerge from a large refactoring. However, the quality of solutions also differed: whereas most developers in the control group fixed the bug using a “quick fix”, those in the experimental group managed to fix the root cause.&lt;/p&gt;

&lt;h3&gt;
  
  
  Discussion
&lt;/h3&gt;

&lt;p&gt;The experimental results show that most of the time the original, unrefactored code was “better” for productivity. However, when the original and refactored code were shown to participants side-by-side, most preferred the refactored code.&lt;/p&gt;

&lt;p&gt;The authors argue that this discrepancy can be explained by the habits of developers, who are used to reading long, procedural methods and thus simply need more time to get used to dealing with multiple classes and methods.&lt;/p&gt;

&lt;p&gt;However, even if refactorings lead to a (possibly temporary) decrease in understandability, the possible increases in maintainability and testability could still make the refactoring worthwhile.&lt;/p&gt;

</description>
      <category>programming</category>
    </item>
    <item>
      <title>Does it matter if you write tests before or after you write your code?</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Mon, 30 Aug 2021 10:34:53 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/does-it-matter-if-you-write-tests-before-or-after-you-write-your-code-43cg</link>
      <guid>https://dev.to/chuniversiteit/does-it-matter-if-you-write-tests-before-or-after-you-write-your-code-43cg</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Adding features during refactoring is counterproductive! It’s a fallacy that may blow up in your face.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I read and summarise software engineering papers for fun, and today we’re having a look at &lt;a href="https://doi.org/10.1109/TSE.2016.2616877" rel="noopener noreferrer"&gt;A dissection of the test-driven development process: Does it really matter to test-first or to test-last?&lt;/a&gt; (2017) by Fucci and others.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Test-driven development is a development practice that involves short, iterative cycles in which the programmer writes tests &lt;em&gt;before&lt;/em&gt; adding new functionality or refactoring existing code. It’s commonly believed that writing tests first leads to higher-quality code and improved productivity. This study puts that belief to the test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;Test-driven development (TDD) has multiple characteristics that set it apart from “traditional” programming, but the “tests first, code later” aspect tends to be the thing that most people talk about (and remember).&lt;/p&gt;

&lt;p&gt;There’s more to it than that however, so let’s talk definitions first.&lt;/p&gt;

&lt;p&gt;TDD is an programming technique which involves cyclic, iterative implementation of new features.&lt;/p&gt;

&lt;p&gt;In each cycle a programmer carries out the following tasks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Writing unit tests for the desired behaviour;&lt;/li&gt;
&lt;li&gt;Writing code to make those tests pass;&lt;/li&gt;
&lt;li&gt;Strictly refactoring code to improve its design, i.e. without modifying
its behaviour (*).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(*) &lt;em&gt;Doing so could nullify or even reverse the benefits of refactoring.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A cycle is finished when all new and existing unit tests pass, and the programmer is content with the program’s design. Ideally, all cycles are short and roughly the same length; around 5 minutes long and never be longer than 10 minutes.&lt;/p&gt;

&lt;p&gt;TDD advocates claim that adherence to these practices will lead to improved quality and productivity.&lt;/p&gt;

&lt;p&gt;In a nutshell, TDD has four characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;sequence&lt;/strong&gt; in which tests are written; before or after coding&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;granularity&lt;/strong&gt; (length) of cycles&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;uniformity&lt;/strong&gt; of cycle lengths&lt;/li&gt;
&lt;li&gt;The amount of effort spent on &lt;strong&gt;refactoring&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How do these four characteristics affect the external quality (**) of the produced software and the developer’s productivity?&lt;/p&gt;

&lt;p&gt;(**) &lt;em&gt;“Does the software do what it’s supposed to do?”&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How the study was conducted
&lt;/h2&gt;

&lt;p&gt;The authors held several five-day workshops about unit testing and TDD at two Nordic companies.&lt;/p&gt;

&lt;p&gt;During the workshop, participants were asked to individually implement three tasks, of which two were greenfield and one was brownfield. Some participants made use of a test-first sequence, while others used a test-last sequence.&lt;/p&gt;

&lt;p&gt;TDD dictates that development is done iteratively using many short cycles. To help participants work on their tasks in small steps, the researchers refined each task into clearly delineated stories and sub-stories. Tasks were then “graded” using acceptance test suites for each user story in order to determine the &lt;strong&gt;quality&lt;/strong&gt; of submitted solutions.&lt;/p&gt;

&lt;p&gt;All participants made use of a special Eclipse IDE that collected information about actions that are performed in it, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code modification&lt;/li&gt;
&lt;li&gt;Test modification&lt;/li&gt;
&lt;li&gt;Code compilation&lt;/li&gt;
&lt;li&gt;Test execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This information is used to determine how participants applied TDD.&lt;/p&gt;

&lt;p&gt;Combining timestamps from the IDE logs with the pass rate of the acceptance test suite allows one to calculate the &lt;strong&gt;productivity&lt;/strong&gt; of each developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What discoveries were made
&lt;/h2&gt;

&lt;p&gt;You probably already guessed by now that &lt;a href="https://en.wikipedia.org/wiki/Betteridge%27s_law_of_headlines" rel="noopener noreferrer"&gt;Betteridge’s law of headlines&lt;/a&gt; strikes again, but in what way?&lt;/p&gt;

&lt;h3&gt;
  
  
  Correlation
&lt;/h3&gt;

&lt;p&gt;Granularity and uniformity are positively correlated, i.e. developers who use shorter cycles are able to keep them consistently short, while those who use larger cycles tend to have cycles of varying lengths. Both factors also appear to affect external quality: smaller cycles and cycles that have consistent lengths are associated with better external quality.&lt;/p&gt;

&lt;p&gt;A small, but statistically significant correlation exists between granularity and refactoring effort: developers who use coarser cycles spend less time on refactoring.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regression
&lt;/h3&gt;

&lt;p&gt;To better understand the relation between TDD’s four characteristic factors and the two outcome variables (quality and productivity), the authors constructed two models.&lt;/p&gt;

&lt;p&gt;The basic idea here is that each model should predict one of the outcome variables using information about the code-test sequence, cycle granularity and uniformity, and refactoring effort.&lt;/p&gt;

&lt;p&gt;A good model is also simple, and should not include superfluous input variables. The process of trimming these variables, feature selection, is described in the original article.&lt;/p&gt;

&lt;p&gt;I’ll simply list the most noteworthy discoveries here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code-test sequence is not part of either model, which suggests that – at least for external quality and developer productivity – it does not matter whether you write your tests before or after your “real” code (***);&lt;/li&gt;
&lt;li&gt;Cycle granularity and uniformity, and refactoring effort are &lt;em&gt;all&lt;/em&gt; negatively correlated with &lt;em&gt;both&lt;/em&gt; quality and productivity.&lt;/li&gt;
&lt;li&gt;The negative correlation between refactoring effort and the two outcome variables is likely due to floss refactoring (****).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(***) &lt;em&gt;This study did not look at the effects on internal quality (i.e. maintainability), which is also pretty important.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;(****) &lt;em&gt;This is a form of refactoring that also includes other activities, like implementation of new features. These new features might not be covered by tests and are therefore more likely to introduce regression bugs.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>testing</category>
    </item>
    <item>
      <title>The hidden costs of résumé-driven development</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Thu, 26 Aug 2021 16:44:01 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/the-hidden-costs-of-resume-driven-development-9mn</link>
      <guid>https://dev.to/chuniversiteit/the-hidden-costs-of-resume-driven-development-9mn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The war is on hold right now, we’ll resume it later&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I read and summarise software engineering papers for fun, and today we’re having a look at &lt;a href="https://doi.org/10.1109/ICSE-SEIS52602.2021.00011" rel="noopener noreferrer"&gt;Résumé-driven development: A definition and empirical characterization&lt;/a&gt; (2021) by Fritzsch and others.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You’ve probably already heard of the &lt;a href="https://agilemanifesto.org/" rel="noopener noreferrer"&gt;agile manifesto&lt;/a&gt;, but did you know there’s also a manifesto for &lt;a href="https://rdd.io/" rel="noopener noreferrer"&gt;resume-driven development&lt;/a&gt;?&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Specific technologies over working solutions&lt;/li&gt;
&lt;li&gt;Hiring buzzwords over proven track records&lt;/li&gt;
&lt;li&gt;Creative job titles over technical experience&lt;/li&gt;
&lt;li&gt;Reacting to trends over more pragmatic options&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fortunately this one’s just satire, but resume-driven development does exist. The term describes a phenomenon where developers choose tech stacks, architectures, methodologies, and protocols not because they are the best tools for the job, but because they look good on a resume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;Hiring is a process that involves two types of stakeholders: employers and applicants. In an ideal world, the employer lists the skills they need in a job advertisment, while job applicants promote the skills that they have in their resumes.&lt;/p&gt;

&lt;p&gt;But we do not live in an ideal world: The hiring process at tech companies is often flawed. Moreover, both employers and applicants tend to oversell the “cool” skills in their advertisements and resumes.&lt;/p&gt;

&lt;p&gt;Such overselling may lead to (costly) disappointment for both parties.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the study was conducted
&lt;/h2&gt;

&lt;p&gt;The researchers conducted an exploratory survey to gain insight from both the hiring and applicant perspectives. Their survey received 591 responses, of which 130 answered for the hiring perspective and 558 for the applicant perspective.&lt;/p&gt;

&lt;p&gt;About 90% of the participants stated Germany as their country of residence, while about 7% is from some other European country. You may want to keep this in mind when you see the results.&lt;/p&gt;

&lt;h2&gt;
  
  
  What discoveries were made
&lt;/h2&gt;

&lt;p&gt;The results tell us there’s some sort of arms race going on between employers and applicants, without actually telling us there’s an arms race going on between employers and applicants.&lt;/p&gt;

&lt;h3&gt;
  
  
  Employers
&lt;/h3&gt;

&lt;p&gt;Employers generally value both &lt;strong&gt;broad&lt;/strong&gt; (73%) and &lt;strong&gt;deep&lt;/strong&gt; (66%) knowledge and experience in technologies. When they have to decide between the two, 42% prefers applicants with broad knowledge, while only 22% would choose an applicant with specialist knowledge.&lt;/p&gt;

&lt;p&gt;When asked whether they believe knowledge and experience in &lt;strong&gt;latest/trending&lt;/strong&gt; technologies or &lt;strong&gt;established&lt;/strong&gt; technologies are important, 85% indicated that the latter are important, while only 59% valued latest/trending technologies. About 39% of respondents prefers applicants who are experienced with established technologies, whereas only 20% prefers applicants who know the latest/trending stuff.&lt;/p&gt;

&lt;p&gt;A majority (59%) of the respondents in this group admits that technology trends and hypes affect what they advertise in their job offerings. An even larger majority (71%) believes that applicants like working with the latest/trending technologies.&lt;/p&gt;

&lt;p&gt;In other words: employers &lt;em&gt;say&lt;/em&gt; they want applicants that have experience with latest/trending technologies, but what they &lt;em&gt;want&lt;/em&gt; are applicants who know established technologies and (that can easily learn) a broad set of different technologies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Applicants
&lt;/h3&gt;

&lt;p&gt;The employers’ belief that applicants enjoy using latest/trending technologies in their work is largely correct. About 73% of them does, while 18% finds it inconvenient or stressful to constantly learn new technologies.&lt;/p&gt;

&lt;p&gt;A large majority (82%) is convinced that using latest/trending technologies in their work makes them more attractive for potential future employers.&lt;/p&gt;

&lt;p&gt;Curiously enough, only 42% of applicant respondents believes that using these novel technologies actually makes them better developers. Moreover, only half (49%) of them had mostly positive experiences with latest/trending technologies. About 20% reported that they once used latest/trending technologies for a project even though they weren’t ideal for the use case.&lt;/p&gt;

&lt;p&gt;Fortunately, in most cases developers tend to select technologies based on a project’s system requirements and the skills that are already available among its developers.&lt;/p&gt;

&lt;p&gt;This suggests that while developers believe that latest/trending technologies are very important, this often does not affect actual selection of technologies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consequences
&lt;/h3&gt;

&lt;p&gt;Resume-driven development may have several consequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If developers choose to use latest/trending technologies that increases the technological diversity in their company. This increases complexity and may negatively impact maintainability and reliability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;False expectations and disappointment about the job may lead to frustrated developers when the actual work turns out to involve different technologies than what was promised.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A strong focus on technologies in hiring criteria may lead to neglect of other (more) important skills and traits, like soft skills, self-motivation and willingness to learn.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>Facebook’s attempts to improve mutation testing</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Wed, 25 Aug 2021 17:45:11 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/facebook-s-attempts-to-improve-mutation-testing-176l</link>
      <guid>https://dev.to/chuniversiteit/facebook-s-attempts-to-improve-mutation-testing-176l</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;White-box testing is possible when you have access to internal structures&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I read and summarise software engineering papers for fun, and today we’re having a look at &lt;a href="https://doi.org/10.1109/ICSE-SEIP52600.2021.00036" rel="noopener noreferrer"&gt;What it would take to use mutation testing in industry – A study at Facebook&lt;/a&gt; (2021) by Beller and others.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mutation testing is a way to determine the quality of your test suite. It works by generating a large number of changed versions of the code, which are called mutants. Examples of changes include deletions of method calls, disabling if conditions, and replacing magic constants.&lt;/p&gt;

&lt;p&gt;If the test suite is good enough, it should be able to “kill” these mutants by having at least one previously succeeding test fail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;The result of mutation tests is a so-called mutation score, which is the ratio of mutants that a test suite manages to kill. Many researchers and developers argue that mutation scores are superior to traditional code coverage, as it’s actually based on a program’s behaviour.&lt;/p&gt;

&lt;p&gt;But mutation testing is not a silver bullet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mutants can be generated in many different ways, which means that mutation testing becomes infeasible for anything but the smallest code bases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is also not clear to developers what they can do to improve the mutation score, and whether an improved score actually has any practical benefits (other than better-looking metrics).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Can these issues be fixed?&lt;/p&gt;

&lt;h2&gt;
  
  
  How the study was conducted
&lt;/h2&gt;

&lt;p&gt;The authors of the paper built a tool that they call Mutation Monkey. It comes with two pipelines, a &lt;strong&gt;training&lt;/strong&gt; and an &lt;strong&gt;application&lt;/strong&gt; pipeline.&lt;/p&gt;

&lt;p&gt;Mutation testing is often very costly – not only because generating all the different mutants takes a lot of time and processing power, but also because many of the generated mutants are easily killed (or not even syntactically valid) and thus useless.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;training&lt;/strong&gt; pipeline solves this problem by semi-automatically learning bug-inducing patterns from three sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/rjust/defects4j" rel="noopener noreferrer"&gt;Defects4J&lt;/a&gt;, a collection of bugs extracted from popular OSS Java projects;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An internal database of fixes for crashes that happened in the production version of the Facebook app. By “reversing” these fixes it becomes possible to reintroduce crashes;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Commits with modifications that made an originally failing test pass.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This process is only partially automated, because experts are still needed to decide which and how many patterns to implement, and for the creation of patch-like templates that implement the patterns.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;application&lt;/strong&gt; pipeline applies the mutation templates to the production version of the code. To reduce the number of mutants that have to be generated (remember, building and testing is expensive!), the pipeline tries to avoid “unprofitable” spots, like logging calls, and runs a light-weight syntax checker to catch syntactically invalid mutants.&lt;/p&gt;

&lt;p&gt;The remaining mutants are submitted to the code review system outside of peak (office) hours, which makes scaling easier and is cheaper. Mutants that pass the test suite are then presented to developers. The pipeline also tells developers which tests visited the mutated block of code. This information should make it easier for developers to decide what they want to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  What discoveries were made
&lt;/h2&gt;

&lt;p&gt;Kill rates were fairly similar across the various mutation patterns. However, some mutations were applied successfully &lt;em&gt;a lot more&lt;/em&gt; than others. For instance, the &lt;code&gt;NULL_DEREFERENCE&lt;/code&gt; pattern was applied almost 2,000 times, while the &lt;code&gt;REMOVED_SYNCHRONIZED&lt;/code&gt; mutations only occurred 143 times within the same period of time.&lt;/p&gt;

&lt;p&gt;Interestingly, the &lt;code&gt;REMOVED_SYNCHRONIZED&lt;/code&gt; is also the only pattern with a much higher kill rate, which suggests that developers are aware that synchronisation-related bugs are hard to debug and thus spend more time writing tests for them.&lt;/p&gt;

&lt;p&gt;The researchers also conducted interviews with 29 developers to learn more about the effectiveness of Mutation Monkey’s approach.&lt;/p&gt;

&lt;p&gt;Most – if not all – developers had not heard of mutation testing prior to the experiment, and needed more information than what was provided by Mutation Monkey.&lt;/p&gt;

&lt;p&gt;However, after explanation from the researchers about 85% believed that Mutation Monkey is a useful tool that could help them write (better) tests. Virtually everyone was also positive about the test coverage information that was included with the test reports.&lt;/p&gt;

&lt;p&gt;However, less than half of the developers confirmed that they would write a test for the gap that Mutation Monkey had found. When asked why not, developers often gave the following reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they want Mutation Monkey to come up with a test;&lt;/li&gt;
&lt;li&gt;the mutated code was of minor importance;&lt;/li&gt;
&lt;li&gt;the mutated code was about to be deprecated;&lt;/li&gt;
&lt;li&gt;the code was still new and likely to undergo iteration before stabilising; and&lt;/li&gt;
&lt;li&gt;the mutated code is in a badly tested part of the code base (😕?!).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, this new approach seems to be better than existing approaches, but still yields too many false positives.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>testing</category>
      <category>engineering</category>
    </item>
    <item>
      <title>Codes of ethics, do they work?</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Tue, 24 Aug 2021 19:37:31 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/codes-of-ethics-do-they-work-1o3o</link>
      <guid>https://dev.to/chuniversiteit/codes-of-ethics-do-they-work-1o3o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Some decisions are ethical, others just Zuck&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I read and summarise software engineering papers for fun, and today we’re having a look at &lt;a href="https://doi.org/10.1145/3236024.3264833" rel="noopener noreferrer"&gt;Does ACM’s code of ethics change ethical decision making in software development?&lt;/a&gt; (2018) by McNamara and others.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Codes of ethics provide guidelines that help you do the right thing, but do they actually work?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;Software developers constantly make ethical considerations, e.g. when deciding how much user data to collect or time to spend on mitigating security risks. Sadly, developers are people and thus don’t always make the right decisions.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Volkswagen_emissions_scandal" rel="noopener noreferrer"&gt;Volkswagen emissions scandal&lt;/a&gt; (also known as Dieselgate) is a highly publicised example of a case where engineers were told to write software that would cause cars to “lie” about their pollution levels during emission tests. The engineers voiced their concerns about this unethical practice internally, but did not inform the authorities. The scandal eventually cost the company more than $30 billion in fines and led to possibly hundreds of early deaths.&lt;/p&gt;

&lt;p&gt;To encourage ethical behaviour many professional organisations, like the &lt;a href="https://chuniversiteit.nl/productivity/why-you-should-join-the-acm" rel="noopener noreferrer"&gt;ACM&lt;/a&gt;, have published a code of ethics that provides guidelines for ethical behaviour. While the effectiveness of such codes of ethics has been studied in the past, no one has done this yet for the computing field.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the study was conducted
&lt;/h2&gt;

&lt;p&gt;A survey was created that described a fictional company that a respondent had just joined as a lead developer. It presented 11 software-related ethical cases, along with an ethical decision, an unethical decision, and an “unsure” option for each case.&lt;/p&gt;

&lt;p&gt;The survey was spread among a large number of software engineering students and professional software engineers. About half of the respondents were simply told that the fictional company had strong ethical standards, while the other half was told that the company followed the &lt;a href="https://www.acm.org/code-of-ethics" rel="noopener noreferrer"&gt;ACM code of ethics&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What discoveries were made
&lt;/h2&gt;

&lt;p&gt;No statistically significant difference was found between the control group and the group that saw a brief version of the code of ethics. Responses from students were also very similar to those from professional software engineers.&lt;/p&gt;

&lt;p&gt;Two of the cases that were presented in the survey were based on recent news stories: the &lt;a href="https://en.wikipedia.org/wiki/Anthony_Levandowski#Civil_lawsuit" rel="noopener noreferrer"&gt;Waymo v. Uber&lt;/a&gt; dispute and the aforementioned Dieselgate scandal. None of the respondents recognised the Waymo dispute, but 20 respondents did mention that they recognised the Dieselgate story.&lt;/p&gt;

&lt;p&gt;The researchers found that those who did not recognise the Dieselgate story were more likely to favour the creation of test-evading software, whereas none of the 20 respondents who recognised the story chose to act unethically.&lt;/p&gt;

&lt;p&gt;This suggests that engineers can be influenced to make more ethical decisions by providing examples of similar news-worthy decisions that make clear that unethical decisions can have undesirable consequences.&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>ethics</category>
    </item>
    <item>
      <title>Six ways to mess up your MVC architecture</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Mon, 23 Aug 2021 10:25:57 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/six-ways-to-mess-up-your-mvc-architecture-3d7h</link>
      <guid>https://dev.to/chuniversiteit/six-ways-to-mess-up-your-mvc-architecture-3d7h</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Focus on the model&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I read and summarise software engineering papers for fun, and today we’re having a look at &lt;a href="https://link.springer.com/article/10.1007/s10664-017-9540-2" rel="noopener noreferrer"&gt;Code smells for model-view-controller architectures&lt;/a&gt; (2018) by Aniche and others.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;Code smells are poor design and implementation choices that hinder comprehensibility and maintainability of code.&lt;/p&gt;

&lt;p&gt;Many studies have shown that code smells make code less maintainable and more prone to bugs. Some smells cause code to be changed more often due to violations of the &lt;a href="https://en.wikipedia.org/wiki/Single_responsibility_principle" rel="noopener noreferrer"&gt;single responsibility principle&lt;/a&gt;, which states that a class or module should have only one reason to change.&lt;/p&gt;

&lt;p&gt;Most of these studies are based on a catalog of code smells that was originally defined by Martin Fowler and Kent Beck in &lt;em&gt;Refactoring&lt;/em&gt;. The smells are generally applicable to any system written in an object-oriented manner, but overlook the role that a class or module may have in the system’s architecture.&lt;/p&gt;

&lt;p&gt;This is why we have to study smells for specific architectures, like MVC. We must learn about their characteristics and impact, so that developers can understand how to avoid those smells and static analysis tools know how to recognise them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the study was conducted
&lt;/h2&gt;

&lt;p&gt;The study makes use of surveys, interviews, and repository mining.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the catalog
&lt;/h3&gt;

&lt;p&gt;The authors started with a three-step data gathering process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A simple survey that asked respondents to list good and bad practices for dealing with models, views, and controllers. The survey yielded 22 complete responses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A more comprehensive survey that aimed to elicit good and bad practices for each of the five major MVC roles (controller, entity, service, component, and repository). This survey was completed by 14 respondents.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unstructured interviews were held about good and bad practices for each of the five roles. The authors interviewed 17 professional developers, all of whom were familiar with the Spring MVC framework.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Two authors performed an open coding process to group good and bad practices into categories. Practices that were not specific to the MVC pattern were discarded.&lt;/p&gt;

&lt;p&gt;The coding process resulted in a list of nine possible smells, which were presented to a core Spring MVC maintainer. Three of the smells were removed because they were specific to Spring and therefore not likely to affect users of other MVC frameworks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding code smells
&lt;/h3&gt;

&lt;p&gt;To understand the characteristics and impact of code smells, the researchers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;analysed 120 Spring MVC projects that are hosted on GitHub;&lt;/li&gt;
&lt;li&gt;asked 21 Spring MVC developers to take part in a survey that assessed their perception of the six code smells;&lt;/li&gt;
&lt;li&gt;looked for experts in development of MVC applications using frameworks other than Spring.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What discoveries were made
&lt;/h2&gt;

&lt;p&gt;I’ll list the code smells first, and discuss their characteristics and impact afterwards.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code smells
&lt;/h3&gt;

&lt;p&gt;Six MVC smells were identified.&lt;/p&gt;

&lt;h4&gt;
  
  
  Promiscuous controller
&lt;/h4&gt;

&lt;p&gt;A controller should provide cohesive operations and endpoints to clients, i.e. it should depend on a limited number of services (at most 3) and handle at most 10 routes (*).&lt;/p&gt;

&lt;p&gt;(*) &lt;em&gt;The values 3 and 10 were derived using a formula that can be found in the original article. Don’t think of these (and other numerical values in this section) as absolute thresholds; they’re more like rules of thumb.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Promiscuous controllers can be broken up into two or more classes until each controller is no longer promiscuous.&lt;/p&gt;

&lt;h4&gt;
  
  
  Brain controller
&lt;/h4&gt;

&lt;p&gt;Flow control in controllers should be very simple, e.g. ideally a controller shouldn’t interpret input to determine what actions to take. Since a controller with a lot of flow control will be littered with method invocations, the researchers argue that the number of non-framework methods that can be executed by a controller should never exceed 55.&lt;/p&gt;

&lt;p&gt;Since business logic is supposed to be implemented in model layer, it has no place in controllers. Any business logic in a brain controller should be moved to an entity, component, or service class.&lt;/p&gt;

&lt;h4&gt;
  
  
  Meddling service
&lt;/h4&gt;

&lt;p&gt;A service should contain business logic and/or handle business logic among domain classes, but never contain SQL queries.&lt;/p&gt;

&lt;p&gt;Data access must always be handled by repositories instead.&lt;/p&gt;

&lt;h4&gt;
  
  
  Brain repository
&lt;/h4&gt;

&lt;p&gt;Repositories are meant to handle anything related to data persistence, but should not contain complicated business logic or complex queries (**).&lt;/p&gt;

&lt;p&gt;(**) &lt;em&gt;More specifically, queries that join multiple tables with complex filters, queries that are constructed dynamically, or objects that are manually assembled from query results.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One could therefore argue that a brain repository is a class whose &lt;a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity" rel="noopener noreferrer"&gt;McCabe’s complexity&lt;/a&gt; exceeds 24 or SQL complexity exceeds 29. Complex logic and SQL queries should live in different methods. Logic that’s used by multiple repositories should be in a component.&lt;/p&gt;

&lt;h4&gt;
  
  
  Laborious repository method
&lt;/h4&gt;

&lt;p&gt;Methods should have only one responsiblity and do one thing. For a repository method, this means that it should execute only one query.&lt;/p&gt;

&lt;p&gt;Methods that execute multiple queries should be split, so that each method only executes one query. Methods can be private or public, depending on whether the persistence action makes sense on its own.&lt;/p&gt;

&lt;h4&gt;
  
  
  Fat repository
&lt;/h4&gt;

&lt;p&gt;Each repository should only deal with a single entity, otherwise it loses its cohesion and becomes harder to maintain.&lt;/p&gt;

&lt;p&gt;If a repository deals with multiple entities, each entity should get its own dedicated repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Characteristics and impact
&lt;/h3&gt;

&lt;p&gt;The most common smell in the analysed dataset is the fat repository (20.5%), followed by the promiscuous controller (12.2%) and the brain controller (7.4%).&lt;/p&gt;

&lt;p&gt;Brain controllers and laborious repository methods are often also affected by the traditional “complex class” code smell and in 59% of cases a brain controller is also a “God class”. The other smells do not appear to overlap at all with traditional code smells, which suggests that the smells in this catalog really are from a distinct category.&lt;/p&gt;

&lt;h4&gt;
  
  
  Impact on change- and defect-proneness
&lt;/h4&gt;

&lt;p&gt;Analysis of Spring MVC projects shows that classes affected by MVC and traditional smells are significantly more prone to changes (almost 3 times more likely) and defects (2 times more likely).&lt;/p&gt;

&lt;p&gt;These differences become smaller when artifact size is taken into consideration (***): classes affected by smells are still prone to changes, but are not more defect-prone.&lt;/p&gt;

&lt;p&gt;(***) &lt;em&gt;More code means more opportunities for bugs to appear, so this isn’t very surprising of course&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are also differences between MVC smells and traditional smells: the latter have a stronger negative impact on change- and defect-proneness.&lt;/p&gt;

&lt;p&gt;Of the six MVC smells, the brain repository and meddling service have the strongest impact on change-proneness, while the meddling service is the only MVC smell that clearly results in more bug-fixing activities.&lt;/p&gt;

&lt;h4&gt;
  
  
  Perception by developers
&lt;/h4&gt;

&lt;p&gt;Developers clearly perceive classes affected by MVC smells as problematic, particularly in the case of the meddling service, fat repository, and brain controller smells.&lt;/p&gt;

&lt;p&gt;Some developers were able to correctly identify and define the smells without prior knowledge of the researchers’ catalog. On the other hand, over half of all participants did not perceive classes affected by the laborious repository method as problematic.&lt;/p&gt;

&lt;h4&gt;
  
  
  Introduction and survival
&lt;/h4&gt;

&lt;p&gt;Once an MVC smell is introduced in a system, it tends to survive for quite a long time. In general, there’s more than 50% chance that a smell will survive for longer than 500 days. Fat repositories even have an 80% chance of surviving more than 1,500 days. 69% of smells are never removed at all.&lt;/p&gt;

&lt;p&gt;These smells are not always caused by code aging (****): some smells already exist when the code artifact is first committed to the repository. For laborious repository methods this even happens 86.5% of the time!&lt;/p&gt;

&lt;p&gt;(****) &lt;em&gt;Do keep in mind that this analysis was done on open source projects. Closed-source projects may have different characteristics.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Generalisability to other frameworks
&lt;/h4&gt;

&lt;p&gt;Most of the identified smells are generalisable to other frameworks (specifically &lt;a href="https://www.vraptor.org/" rel="noopener noreferrer"&gt;VRaptor&lt;/a&gt;, &lt;a href="https://rubyonrails.org/" rel="noopener noreferrer"&gt;Ruby on Rails&lt;/a&gt;, &lt;a href="https://www.asp.net/mvc" rel="noopener noreferrer"&gt;ASP.NET MVC&lt;/a&gt;, and &lt;a href="https://www.playframework.com/" rel="noopener noreferrer"&gt;Play!&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Application built using frameworks that use the &lt;a href="https://en.wikipedia.org/wiki/Active_record_pattern" rel="noopener noreferrer"&gt;active record pattern&lt;/a&gt; don’t appear to suffer from meddling services and generally don’t use repositories, which would essentially eliminate three of the MVC smells. Instead, they’re more likely to suffer from fat &lt;em&gt;models&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Should you copypaste code from Stack Overflow?</title>
      <dc:creator>Chun Fei Lung</dc:creator>
      <pubDate>Sat, 21 Aug 2021 11:12:23 +0000</pubDate>
      <link>https://dev.to/chuniversiteit/should-you-copypaste-code-from-stack-overflow-4f11</link>
      <guid>https://dev.to/chuniversiteit/should-you-copypaste-code-from-stack-overflow-4f11</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Hot answers aren’t always the best answers&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I read and summarise software engineering papers for fun, and today we’re having a look at &lt;a href="https://doi.org/10.1145/3180155.3180260" rel="noopener noreferrer"&gt;Are code examples on an online Q&amp;amp;A forum reliable? A study of API misuse on Stack Overflow&lt;/a&gt; (2018) by Zhang and others.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;If you’re stuck with a programming problem or have just started experimenting with a new framework or library, code examples on Stack Overflow can be tremendously helpful.&lt;/p&gt;

&lt;p&gt;Many of them are short and to the point, which makes them easy to understand and reuse.&lt;/p&gt;

&lt;p&gt;Unfortunately, herein also lies the rub: the code examples don’t always show all the code that one &lt;em&gt;should&lt;/em&gt; use in a production environment.&lt;/p&gt;

&lt;p&gt;For example, a code example might show how to open and read from a file, but neglect to point out that you first need to check whether that file actually exists or that the file handle should be closed afterwards.&lt;/p&gt;

&lt;p&gt;This may cause all kinds of issues when software is deployed in a production environment, like resource leaks and program crashes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the study was conducted
&lt;/h2&gt;

&lt;p&gt;The goal of the study is to determine whether and how code examples on Stack Overflow differ from best practices when it comes to using libraries.&lt;/p&gt;

&lt;p&gt;Discovering these best practices is far from trivial: the number of libraries are countless, and each has its own gotchas and best practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mining GitHub
&lt;/h3&gt;

&lt;p&gt;The authors therefore designed a tool called &lt;a href="https://web.cs.ucla.edu/~tianyi.zhang/examplecheck.html" rel="noopener noreferrer"&gt;ExampleCheck&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;ExampleCheck infers API usage in three steps. More specifically, it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;searches GitHub for snippets in which an API’s method is invoked. It then uses program slicing to filter out statements that are specific to the program. The result is a normalised representation (*) that consists of a sequence of statements that are related to the invoked method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;identifies common patterns in the sequence of statements surrounding calls to the API’s method. Additionally, it filters out calls that are used in only a few outlier examples.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;determines which guard conditions should precede API method calls. This is done by first creating canonicalised versions in which project-specific predicates are replaced with &lt;code&gt;true&lt;/code&gt; and API-specific variables are given generic names. The conditions are then simplified and merged until only the most frequently appearing patterns remain.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(*) &lt;em&gt;This means that things that are specific to the analysed project, like code style are converted such that two snippets from two different programs that essentially do the same thing will look identical to each other.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The authors ran ExampleCheck on 380,000 GitHub projects for 100 popular Java API methods from 9 different domains. On average, each method has about 55,000 associated snippets, ranging from 211 to more than 450,000.&lt;/p&gt;

&lt;p&gt;ExampleCheck infers 245 API usage patterns. Manual inspection shows that 180 of those patterns are usable for the next part of the study.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mining Stack Overflow
&lt;/h3&gt;

&lt;p&gt;The authors extract code snippets from all Stack Overflow answer posts that mention one of the 100 Java API methods, and gather some additional information for each post, like the number of votes and whether the post was accepted as a correct answer.&lt;/p&gt;

&lt;p&gt;ExampleCheck is used to check whether the sequence of method calls in each snippet is subsumed by one of the identified API usage patterns.&lt;/p&gt;

&lt;p&gt;A manual verification of 400 randomly selected posts suggests that about three quarters of the reported posts are true positives.&lt;/p&gt;

&lt;p&gt;False positives are generally caused by a lack of deep knowledge about postconditions of methods and usage patterns that are correct, but not used very frequently. Finally, warnings in natural text and examples that are distributed over several &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; blocks also result in false positives.&lt;/p&gt;

&lt;h2&gt;
  
  
  What discoveries were made
&lt;/h2&gt;

&lt;p&gt;ExampleCheck detects potential API misuse in 31% of Stack Overflow posts that were considered for this study.&lt;/p&gt;

&lt;p&gt;If reused without modification, the code in these posts would likely result in crashes (76%), incomplete actions (18%), or resource leaks (2%).&lt;/p&gt;

&lt;p&gt;Specifically, APIs for databases, IO, and networking often lack exception handling and proper closing of resources. Examples for cryptography APIs and string manipulation are unreliable for similar reasons: input and output should always be validated, especially if a method might return a &lt;code&gt;null&lt;/code&gt; value or throw exceptions.&lt;/p&gt;

&lt;p&gt;This wouldn’t really be an issue if it was clear to readers which posts contain API misuse. Unfortunately, that isn’t the case.&lt;/p&gt;

&lt;p&gt;For instance, highly voted posts aren’t necessarily more reliable. Moreover, posts with API misuse have &lt;em&gt;more&lt;/em&gt; views on average than posts without any misuse. A possible reason for this is that highly voted posts tend to contain concise step-by-step explanations, i.e. they’re written for simplicity and readability rather than real-world circumstances.&lt;/p&gt;

&lt;p&gt;It would be helpful if Stack Overflow were to provide some method to show best practices next to code snippets in answer posts. The authors propose a browser extension that adds this functionality. You can find a screenshot and description of the extension in the original article.&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
