move-imports, o cómo calmar el TOC de un pythonista

Una historia de éxito: un grupito pequeño de programadores (o quizas sólo uno) a pura pasión, café y feedback de sus usuarios mete miles de lineas de código que logran hacer funcionar un negocio.

Parte del éxito, supongamos, es porque el sistema está hecho en Python, que se eligió porque es versátil y pragmático para obtener resultados rápidos. Pero se sabe: en el vértigo la pasión, el feedback y el café no cabían muchas elegancias ni había tiempo para estilos o convenciones. Caminante no hay camino, se hace camino al andar, dijo Machado, refiriéndose a la deuda técnica que toman las startups en sus inicios.

El negocio comienza a crecer, hay más demandas de los clientes y la cosa está tan fea que algo, alguito, hay que mejorar. Como, por suerte, la cosa va bien, se contratan nuevos programadores que tengan experiencia en Python específicamente. Y estos nuevos programadores experimentados, los pythonistas, vienen con sus mañosas convenciones del lenguaje a cuestas. Una de ellas está tallada en piedra: salvo ineludibles excepciones, los imports van en la cabecera del módulo y en un orden en particular.

Hay justificación, dicen los pythonistas. Simplificar la lectura, saber a simple vista de qué depende un módulo, tener bloques de código más chicos, no repetirse. Pero, aceptémoslo, es un TOC.

Leer más…

El mono salta entre las ramas. El desarrollador también

Cuando laburamos con git, necesitamos frecuentemente cambiar de rama, sea porque estamos haciendo un feature mientras esperamos que alguien haga review de otra cosa y eventualmente pide algo, sea porque somos nosotros los que checkouteamos el branch de un compañero para probar algo.

Ir y volver entre ramas es fácil porque basta usar - que es un alias del branch previo.

$ git checkout master
Switched to a new branch 'master'
$ git checkout -
Switched to branch 'writing'

git checkout - es equivalente a la forma general git checkout @{-1} y si cambiamos el -1 por -N volveremos al enésimo branch en que estuvimos.

El problema es que si no nos acordamos el nombre del branch, mucho menos podriamos acordarnos el orden cronológico en el que lo usamos.

Leer más…

Miau: cuando el gato dice la verdad

Cuando se cumplieron los primeros 7 meses de su gestión, el presidente Macri dió una entrevista exclusiva a periodistas del canal Telefé. Horas después apareció este video en las redes, cuyo autor o autora desconozco:

Ahí estaba el humor, el fruto más gozoso del ingenio popular, para salvarnos a carcajadas. No para evadirnos de la realidad sino, al contrario, para vencerla, para enfrentar la amargura que algunas certezas traen (ya sabíamos a esa altura, con devaluación a precios y tarifazos en curso, que las advertencias no habían sido una "campaña del miedo"). Pero era aún más: era un ejemplo de ese humor que enuncia verdades difíciles de escuchar de otra manera.

Simplemente me pareció genial. Me acordé, por supuesto, de la entrevista a Homero en el capítulo de la Venus de jalea y también de un cortometraje español que ví hace mucho titulado "Lo que tú quieras oir", cuyo argumento se basa exáctamente en la creación de un mash-up de audio como alivio de una situación dramática.

Cada discurso o entrevista de Macri me parecía (me parece) un puesta en escena cínica, plagada de mentiras, floja de fonética y con pésimo acting. Necesitaba más de estos videos que le hagan decir la verdad.

Leer más…

El padronazo cordobés

Open Data Córdoba es un colectivo abierto y multidisciplinario sin fines de lucro cuyo objetivo principal es difundir y transparentar el uso de la tecnología y los datos masivos para beneficio del conjunto de la sociedad, especialmente en la provincia de Córdoba.

El grupo nació en época de elecciones, intentando echar un manto de luz a las sospechas fundadas de desprolijidades en el escrutinio provisorio de las legislativas de 2013. Luego de muchas otras iniciativas y bastante perseverancia docente de algunos de nuestros compañeros, nuestra contribución ha empezado a ser reconocida desde los medios locales, algunas agrupaciones políticas y otras organizaciones de la sociedad civil que abogan por la transparencia y el fortalecimiento de las instituciones.

En este contexto, el portal de noticias Cba24N, perteneciente al grupo de Servicios de Radio y Televisión (SRT) de la Universidad Nacional de Córdoba, nos ha invitado a realizar análisis de datos "en vivo" el próximo 25 de octubre, día de las elecciones nacionales.

Hay muchas ideas para ese día que ojalá podamos llevar adelante, aunque vale resaltar (atajarse) que se trata de una tarea totalmente voluntaria . Mientras tanto, el domingo pasado me dediqué a jugar con algunas agregaciones sobre el padrón de Córdoba para encontrar "notas de color" analizando nombres y apellidos de los votantes

Leer más…

Curso de Python para ciencias e ingeniería, nueva edición

/images/Newsletter4-Banner_20120705_12-44-50-800.jpg

¡Atención!

¿Estás interesado en que dicte este curso, de manera intensiva, en tu laboratorio o empresa? Contactame.

Está abierta la inscripción para el nuevo dictado de mi curso de introducción a Python para ciencias e ingenierías, en la Facultad de Ciencias Exáctas, Físicas y Naturales de la Universidad Nacional de Córdoba (aprobado como curso de extensión - Resolución 1272/2015, bajo el nombre "Python como herramienta para la ingeniería") desde el miércoles 14 de ocubre de 18 a 22hs, durante 5 semanas.

Este curso una versión mejorada del que dicté en la Facultad de Matemática, Física y Astronomía en mayo pasado, avalado como curso de extensión (Resolución HCD 107/2015)

El precio está absolutamente subsidiado por las ganas de que más ingenieros e investigadores programen Python. No te demores en anotarte , los cupos son muy limitados!

Se entregarán certificados a quienes completen asistencia.

Leer más…

Curso de Python para ñoños

¡Los cupos irán a sorteo! Anotate. Si no entrás para en esta edición, quedás anotado para la próxima que será muy pronto.

La demanda nos desbordó. En menos de 2 dias tenemos inscriptos para llenar dos veces el laboratorio que tenemos disponible! Algunos ya están averiguando la disponibilidad del Estadio Kempes para hacer el próximo.

Como recién hoy (martes 7 de abril) se realizó la difusión oficial desde FaMAF, la decisión de los organizadores es permitir la inscripción de todos los interesados y hacer un sorteo de las 25 plazas aranceladas y otro para las 15 plazas gratuitas reservadas para estudiantes de grado de FaMAF.

La justificación de un sorteo en vez de tomar el orden de inscripción la dió el Dr. Nicolás Wolovick, que junto al Dr. Pedro Pury fueron los gestores para que el curso se oficializara, con un argumento democráticamente ñoño:

Estar conectado 24/7 por 3G, recibir el tweet, e inscribirse, no es justo, es una condición de posibilidad que no todos tienen. La distribución uniforme es la que mayor entropía tiene :)

Si estás interesado, es importante que te inscribas a través del formulario. Así tendremos una lista bien grande de "argumentos" para reeditar el curso lo más pronto posible.

Otra posibilidad es que averigües hagas lobby en tu empresa o laboratorio sobre la posibilidad de realizar el curso in house y, si tienen interés, lo charlamos.


/images/Newsletter4-Banner_20120705_12-44-50-800.jpg

A partir del 29 de abril voy a dar el curso Introducción a Python para ciencias e ingenierías en la Facultad de Matemática, Astronomía y Física (FaMAF) de la Universidad Nacional de Córdoba.

Este curso es una versión revisada y extendida del que dí en la ScipyCon Argentina 2014 y durará 8 clases de 2hs cada una. Será los miércoles de 18hs a 20hs en el laboratorio de computación de la facultad. No hace falta contar con equipo propio y el único pre-requisito es tener nociones básicas de programación en cualquier lenguaje.

El costo del curso es $400. Hay becas para estudiantes de grado de FaMAF.

Acá está el formulario de pre-inscripción (LOS CUPOS IRAN A SORTEO).

El curso está reconocido como Curso de Extensión de FaMAF (Res. HCD 107/2015) y se entregarán certificados oficiales a quienes completen asistencia y participación.

Atención Los cupos son muy limitados!

Leer más…

Sergio Massa y #LaGente

Anoche me reí mucho con el hashtag #LaGente, que se viralizó mientras Alejandro Fantino entrevistaba, una vez más, al inefable candidato presidencial Sergio Massa.

Me acordé entonces de un post de Zulko, cuyo blog es un compilado de gemas ñoñamente divertidas. Allí muestra cómo recortar automáticamente los pedacitos de un video que mencionen una palabra o frase, basándose en las marcas de tiempo del archivo de subtítulos, utilizando su maravillosa biblioteca Moviepy y un poco de Python. Más o menos lo que hace videogrep, pero más prolijo.

La herramienta youtube-dl (que también es genial y hecha en Python), permite no sólo bajar videos de youtube y los subtitulos existentes, sino que también puede bajar el "subtitulo automático". En general son bastante malos pero es suficientemente efectivo para encontrar pequeñas frases.

Todo sea por "la gente": manos a la obra

Lo primero que necesitamos es una lista de videos donde Sergio Massa hable. Hice una búsqueda, decidí ignorar algunos (parodias, por ejemplo) y generé una lista. Hay varias maneras de obtener este listado de las primeras paginas de resultados, yo utilicé el rústico y efectivo webscrapping:

In [1]:
from pyquery import PyQuery
links = []
skip = ('M0yuFHbhYLY','TLmMh9Qvmic', 'rY4Hwvn6GlA')

for page in range(1, 5):
    pq = PyQuery('https://www.youtube.com/results?search_query=entrevista+sergio+massa&page=%s' % page)
    pq.make_links_absolute()
    links.extend([pq(a).attr('href') for a in pq('a.yt-uix-tile-link') if pq(a).attr('href').split('v=')[1] not in skip])
links
Out[1]:
['https://www.youtube.com/watch?v=8pP8G3fSAcY',
 'https://www.youtube.com/watch?v=g6QSwxUo1aw',
 'https://www.youtube.com/watch?v=_9FN6CI8fD4',
 'https://www.youtube.com/watch?v=5wqwNDpkZOo',
 'https://www.youtube.com/watch?v=V865E4mBiHU',
 'https://www.youtube.com/watch?v=TPrGNJnMS9U',
 'https://www.youtube.com/watch?v=SVTl11hG9Gs',
 'https://www.youtube.com/watch?v=Df_dwb5XHQM',
 'https://www.youtube.com/watch?v=sptBkyfq1VU',
 'https://www.youtube.com/watch?v=tzjz1xrNu3k',
 'https://www.youtube.com/watch?v=k-CGbuOo8do',
 'https://www.youtube.com/watch?v=_L-B_wHsEec',
 'https://www.youtube.com/watch?v=iFOABIQdo9Q',
 'https://www.youtube.com/watch?v=WOlRIKGrBWY',
 'https://www.youtube.com/watch?v=a-mCgN6W9ek',
 'https://www.youtube.com/watch?v=x5vhchv3zAY',
 'https://www.youtube.com/watch?v=bi5eK7i59w0',
 'https://www.youtube.com/watch?v=VNHV3D_6o4E',
 'https://www.youtube.com/watch?v=MWVZ6JDU9V8',
 'https://www.youtube.com/watch?v=v-JmdgVZqVc',
 'https://www.youtube.com/watch?v=FBFHpdxsyYU',
 'https://www.youtube.com/watch?v=WXmTc83l1sQ',
 'https://www.youtube.com/watch?v=GfNgds5vS60',
 'https://www.youtube.com/watch?v=UHRa34A6rDg',
 'https://www.youtube.com/watch?v=xVU-EjnuksU',
 'https://www.youtube.com/watch?v=-IXymTZZM6o',
 'https://www.youtube.com/watch?v=tzvwDTPyTHQ',
 'https://www.youtube.com/watch?v=a19z6EVWpQ4',
 'https://www.youtube.com/watch?v=rAOvF8X_nzM',
 'https://www.youtube.com/watch?v=wtvl4esdMGU',
 'https://www.youtube.com/watch?v=1YPHDDH1Az0',
 'https://www.youtube.com/watch?v=w7TnghsrJUo',
 'https://www.youtube.com/watch?v=qBT-6HpSrwc',
 'https://www.youtube.com/watch?v=JM-xblTxLGc',
 'https://www.youtube.com/watch?v=kMymsVsmETY',
 'https://www.youtube.com/watch?v=K1-dfiVfbOI',
 'https://www.youtube.com/watch?v=VnoiHVlR-So',
 'https://www.youtube.com/watch?v=hMTzJyLiXE4',
 'https://www.youtube.com/watch?v=VGQPNQ1Bhkg',
 'https://www.youtube.com/watch?v=0oR4z7SsY14',
 'https://www.youtube.com/watch?v=Cl4r8h_Hlak',
 'https://www.youtube.com/watch?v=gJFmek-YgYo',
 'https://www.youtube.com/watch?v=9VQ7Ov5W_tM',
 'https://www.youtube.com/watch?v=rKwKImVrYu4',
 'https://www.youtube.com/watch?v=LJwj9SHC9EU',
 'https://www.youtube.com/watch?v=-08OEpFThiw',
 'https://www.youtube.com/watch?v=BPJBl5y2P2g',
 'https://www.youtube.com/watch?v=MvkXlg9ZbL4',
 'https://www.youtube.com/watch?v=7KgIa4fX_Ng',
 'https://www.youtube.com/watch?v=upNLrHtzeBI',
 'https://www.youtube.com/watch?v=Y-norf1BKAs',
 'https://www.youtube.com/watch?v=QMvAl_fxQSA',
 'https://www.youtube.com/watch?v=3os_uXUOvcM',
 'https://www.youtube.com/watch?v=ZE_aChIEELo',
 'https://www.youtube.com/watch?v=iKI-8ceuR-A',
 'https://www.youtube.com/watch?v=CASdYLquQII',
 'https://www.youtube.com/watch?v=5cvyi1CcpYs',
 'https://www.youtube.com/watch?v=NVEw-YIAy5A',
 'https://www.youtube.com/watch?v=yMXn04-GQTY',
 'https://www.youtube.com/watch?v=RCCzZGcGg5k',
 'https://www.youtube.com/watch?v=FqMFKGsXLOE',
 'https://www.youtube.com/watch?v=MVOvQb8KBm0',
 'https://www.youtube.com/watch?v=ENvWfMwnJ_0',
 'https://www.youtube.com/watch?v=bs7xGm293Vs',
 'https://www.youtube.com/watch?v=7OvrK-U-axI',
 'https://www.youtube.com/watch?v=VHeWqPqs4vo',
 'https://www.youtube.com/watch?v=nVOEi9FESn8',
 'https://www.youtube.com/watch?v=eikTWAvFwTE',
 'https://www.youtube.com/watch?v=BU2amn3QdWk',
 'https://www.youtube.com/watch?v=GiB1pOuEvqg',
 'https://www.youtube.com/watch?v=GAPN17lTJ9c',
 'https://www.youtube.com/watch?v=4Ja1uZbMM8E',
 'https://www.youtube.com/watch?v=F1dAfCR4rc0',
 'https://www.youtube.com/watch?v=334O9xh-CQY',
 'https://www.youtube.com/watch?v=KgNmw3sJ0g8',
 'https://www.youtube.com/watch?v=-SQSue4-PLk',
 'https://www.youtube.com/watch?v=HPE4PHlYySo']

Luego, el paso lento: bajar los videos. Al parecer, Youtube no genera un subtitulo automático para videos demasiado largo, así que limité hasta 30 minutos.

In [2]:
for link in links:
    !youtube-dl --write-auto-sub --sub-lang es --max-filesize 30.00m {link}

Con el material crudo disponible (aunque puede ser que no se hayan encontrado subtitulos para todos los videos), podemos copiar descaradamente partes del código de Zulko (levemente adaptado)

In [3]:
import re 
import os
import glob
import random
from moviepy.editor import VideoFileClip, concatenate, TextClip, CompositeVideoClip


def convert_time(timestring):
    """ Converts a string into seconds """
    nums = [float(t) for t in re.findall(r'\d+', timestring)]
    return 3600 * nums[0] + 60*nums[1] + nums[2] + nums[3]/1000


def get_time_texts(file):
    with open(file) as f:
        lines = f.readlines()

    times_texts = []
    current_times , current_text = None, ""
    for line in lines:
        times = re.findall("[0-9]*:[0-9]*:[0-9]*,[0-9]*", line)
        if times != []:
            current_times = [convert_time(t) for t in times]
        elif line == '\n':
            times_texts.append((current_times, current_text))
            current_times, current_text = None, ""
        elif current_times is not None:
            current_text = current_text + line.replace("\n"," ")
    return times_texts

def find_word(word, times_texts, padding=.4):
    """ Finds all 'exact' (t_start, t_end) for a word """
    matches = [re.search(word, text)
               for (t,text) in times_texts]
    return [(t1 + m.start()*(t2-t1)/len(text) - padding,
             t1 + m.end()*(t2-t1)/len(text) + padding)
             for m,((t1,t2),text) in zip(matches, times_texts)
             if (m is not None)]


def get_subclips(video_path, cuts):   
    video = VideoFileClip(video_path)
    return [video.subclip(start, end) for (start,end) in cuts]


def get_all_subclips_for(word, pattern='*.mp4', sub_ext='.es.srt', shuffle=True):
    subclips = []
    for mp4 in glob.glob(pattern):
        sub = os.path.splitext(mp4)[0] + sub_ext
        try:
            times = find_word(word, get_time_texts(sub))
        except IOError:
            # ignore video if it hasn't subtitle
            continue
        cuts = get_subclips(mp4, times)
        subclips.extend(cuts)
    if shuffle:
        random.shuffle(subclips)
    return subclips

La función get_all_subclip recibe la frase a buscar y devuelve un listado de segmentos donde, muy probablemente, se pronuncia.

In [4]:
gente = get_all_subclips_for('la gente')
len(gente)
Out[4]:
77

El problema es que aunque es muy probable que sea Sergio Massa el que diga "la gente" en sus entrevistas, a veces es el entrevistador, a veces youtube entendió mal al desgrabar y a veces el código recortador la pifia. Por este motivo hay que descartar los segmentos que no sirven.

Se me ocurrió hacerlo visualmente: los pegué todos, superponiendo el índice al que corresponde cada segmento, para luego anotar los que no sirven y filtrarlos en otra pasada.

In [5]:
def make_preview(subclips):
    subclips_ = []
    for (i, clip) in enumerate(subclips):
        txt_clip = TextClip(str(i),fontsize=70, color='white')
        txt_clip = txt_clip.set_pos('center').set_duration(clip.duration)
        clip = CompositeVideoClip([clip, txt_clip])
        subclips_.append(clip)

    final = concatenate(subclips_, method='compose')
    final.write_videofile('preview.webm', codec='libvpx', fps=24)    
In [6]:
make_preview(gente)
[MoviePy] >>>> Building video preview.webm
[MoviePy] Writing audio in previewTEMP_MPY_wvf_snd.ogg
[MoviePy] Done.
[MoviePy] Writing video preview.webm
[MoviePy] Done.
[MoviePy] >>>> Video ready: preview.webm 

El resultado me permitió hacer el tamizado

In [7]:
ignore = [2, 3, 8, 12, 17, 19, 25, 28, 32, 36, 38, 40, 41, 44, 49, 55, 56, 61, 62, 66, 73, 74]
subclips_cleaned = [i for j, i in enumerate(gente) if j not in ignore]

Aunque no tengo idea de edición de videos, y porque de verdad creo que es un demamogo impresentable que no debería presidir ni una junta vecinal, quería darle un toque final, con una pequeña frase

In [8]:
import numpy as np
from moviepy.video.tools.segmenting import findObjects

def arrive(screenpos,i,nletters):
    v = np.array([-1,0])
    d = lambda t : max(0, 3-3*t)
    return lambda t: screenpos-400*v*d(t-0.2*i)

screensize = (640,360)
txtClip = TextClip('Yn tragr ab rf obyhqn'.decode('rot13'), color='white', font="Amiri-Bold", kerning=5, fontsize=50)
cvc = CompositeVideoClip( [txtClip.set_pos('center')],
                        size=screensize)

letters = findObjects(cvc) # a list of ImageClips

def moveLetters(letters, funcpos):
    return [ letter.set_pos(funcpos(letter.screenpos,i,len(letters)))
              for i,letter in enumerate(letters)]

ending = CompositeVideoClip(moveLetters(letters, arrive), size=screensize).subclip(0, 10)
In [9]:
# le damos una mezcladita más
random.shuffle(subclips_cleaned)
subclips_cleaned.append(ending)
make_final(subclips_cleaned, 'massa_lagente_final.webm')
[MoviePy] >>>> Building video massa_lagente_final.webm
[MoviePy] Writing audio in massa_lagente_finalTEMP_MPY_wvf_snd.ogg
[MoviePy] Done.
[MoviePy] Writing video massa_lagente_final.webm
[MoviePy] Done.
[MoviePy] >>>> Video ready: massa_lagente_final.webm 

Y este es el resultado:

In [ ]:
 

Formas en que los hombres de tecnología son involuntariamente sexistas

¡Atención!

esta es una traducción del artículo Ways Men In Tech Are Unintentionally Sexist de Kat Hagan

Formas en que los hombres de tecnología son involuntariamente sexistas

Un amigo publicó esto en twitter:

Realmente respeto

I really respect the amount of self-awareness it takes to ask that question! It’s easy to disavow the trolls sending rape and death threats, but it takes much more courage to acknowledge that you might be perpetuating harmful attitudes in less-obvious ways.

[Author's Note: I felt like it was important to establish some context, but you can also skip the 101-level discussion and jump right to the list.]

This question hints at two important concepts: implicit biases and microaggressions.

We have all internalized harmful stereotypes about women — it’s part of growing up in a culture that inculcates gender roles from a very early age. Our culture has deeply-embedded patriarchal power structures (ditto racist and classist and ableist and transphobic and homophobic and so on…) that we all absorb and have to intentionally question and deprogram. We all, regardless of our background or our conscious beliefs, have implicit biasesthat affect the way we see the world.

Groups that are dominated by one sort of person tend to develop ways of talking and thinking that implicitly center the identities and experiences of that one sort of person, which becomes a self-perpetuating cycle, because it communicates to outsiders that they are different (at best; unwelcome interlopers or second-class citizens, at worst). It can introduce, or exacerbate, the further self-fulfilling prophecies of impostor syndrome and stereotype threat. It can put pressure on people to conform to a certain type in order to succeed.

This context is the heart of why inclusive language matters, why a seemingly-harmless joke isn’t that harmless, and why small things seem to sometimes get blown out of proportion.

Which brings us to microaggressions: “social exchanges in which a member of a dominant culture says or does something, often accidentally, and without intended malice, that belittles and alienates a member of a marginalized group.”

These are little things. Things that many people do without thinking about them and certainly without intending anything by them. Things that individually are meaningless, but in aggregate set the tone of an entire community.

Little things reinforce stereotypes and implicit biases instead of challenging them. They insulate members of the dominant group from having to confront their own biases. They communicate underlying attitudes and community norms. Language may or may not shape the way we think, but it is a powerful signal about what sort of behavior is and is not acceptable, and what your personal expectations are.

Worse, those little things can subtly reinforce the attitudes of actual abusers and signal that they are welcome in our community. (Example: rape jokes are seen as tacit nods of approval by actual rapists.)

Communication is tricky even on the best of days; the best defense against misunderstandings is to develop a finely-tuned sense of empathy, and try to notice as much as possible what we’re doing that might create distance from someone else and keep us from questioning our own assumptions about the world.

Sometimes it’s hard to see these things without getting defensive, or going too far down the road of guilt and excessive self-flagellation. I think it’s important to realize that every single one of us makes this kind of mistake, no one is immune. The determination of character, in my opinion, isn’t whether you slip up, but what you do about it afterward.

If you care about others, nothing feels worse than realizing you accidentally stepped on someone else’s foot. I really think it’s a natural reaction to bristle a bit, to try to minimize it, to protect ourselves from feeling bad. Once I recognized that defensiveness as a natural part of the process, it was much easier for me to realize I was doing it, then apologize and move on instead of digging myself deeper. It takes practice.

The good news, though, is that little things are easy to change. Personally I believe that if you can change the outward tone of a culture, you stand a good chance of changing the actual beliefs and attitudes of that culture.

Caveats: not everyone notices or cares about every single thing on this list, and I’ve probably missed some that my own privilege blinds me to. This is a list specifically focused on sexist microaggressions; while some of the things on this list might also apply to, for instance, transfolk or non-binary folks or people of color, I can’t claim to speak for anyone other than myself.

The post is written as “things men do”, because that’s the question that was asked, but of course anyone can (and does) perpetuate harmful stereotypes.

Finally, this list is written for those who, like me, try to err on the side of being maximally-inclusive. Many of these things are common in our culture, and while I try to model good behavior, I don’t correct others’ usage unless they ask. I consider this an application of the robustness principle.

So, without further ado.


1. Using “guys” to mean “people”.

I fear I’m earning a bit of a reputation for this one among my colleagues, as I sometimes good-naturedly respond to “Hey guys, [question]?” with “I’m not a guy, but [answer]”. Yes, most people intend this in a gender-neutral way; no, it is not actually gender-neutral. If you think about it, “guys” is only gender-neutral in a situation where maleness is the assumed default.

Many women don’t notice or mind this, but to some in our male-dominated field it can be a tiny, pointed reminder of the extra work they have to do just to fit in, be seen, be taken seriously.

Personally, it can also make me wonder if I’m being seen at all; I often read a message to a mailing list, or in a chat room, that begins “hey guys” and wonder whether the speaker realizes that not everyone on the list is a man. Worse, I worry it sends the wrong message to other women who might observe the exchange. For instance, if a woman was thinking of getting involved in WordPress development, could all the “guys” messages on the wp-hackers list make her think there aren’t any women in that community?

Don’t do the “guys and girls” thing either, which is marginally better but still makes it feel like an afterthought. Try: “folks”, “y’all”, “everyone”, “team”, “channel”, or just “awesome people”. :) If my own experience is any indication, it’ll sound weird for a month or two and then become normal.

Relatedly, avoid assuming male users in your documentation. Just stop worrying and embrace the singular “they”.

2. Similarly: “girls” for “women”.

Yes, I know it’s the best we have as an informal analogue to “guys”, but it infantilizes women and sounds patronizing. It might subconsciously encourage us to take women less seriously. In general, “girl” should be used to refer to female children only. Like “guys”, this will sound weird for about a month and will then become normal.

Some folks are reclaiming “lady” for informal usage, but I’ve found that can be a bit loaded (personally, I don’t think of myself as a lady; when I was a child, my grandfather would reprimand me for wearing jeans or climbing trees, because those things were “unladylike”). YMMV, but for people you don’t know well, I would stick to “women”.

3. “Mom” as an example of a non-technical user.

I know: your mom, like a lot of people, may not be very good with computers. (My mom, on the other hand, while she doesn’t really give herself credit for it, is quite good at figuring computer stuff out. She programmed with punchcards in college and can do things with Excel that I have no idea how to do. It’s my dad who always needs computer help.)

This tired old trope erases the vast number of computer-literate women who happen to be mothers, as well as encouraging condescension. Again, the context here is a society and a professional field where women already struggle to be taken seriously; no need to pile on.

This trope has its own article on the Geek Feminism Wiki, which suggests alternatives: “When the purpose of the statement is to convey the idea that something is “really simple”, ideal nouns will refer to non-human or purely technical categories, such as cat, non-technical user, Ubuntu user, or “newbie.””

4. Using avatars that are male by default.

If the default (or unset) avatar on your site reads as male, you’re making an implicit statement that your “normal” user is male and anyone else is an exception. Personally, I think using a non-gendered (even non-human) avatar can really showcase an app’s creativity.

5. Describing software or algorithms as “sexy”, “hot”, etc.

By sexualizing something that does not need to be sexualized, you’re creating a college-frat-boy type environment, as well as implicitly conflating quality with sexual attractiveness. If I work with you, I want to know that you’re enough of an adult to be able to appreciate something (or someone) without wanting to fornicate with it.

Anyhow, it’s vague. What is so great about it? Is it really efficient, does it solve a problem in a new way, does it scale really well, does it have a great UI?

Related: Referring to hardware (or cars, or whatever) by female names or pronouns. Yeah, okay, grand naval tradition and all that, but it’s still kind of weird. Can you not tell the difference between women and objects?

6. Assuming women they meet are in non-technical roles.

If you meet a woman in a professional setting, like a conference (or the afterparty!), your first assumption should be that she’s there because she’s interested in the material. This seems obvious, but most women have had the unfortunate experience of being assumed to be “the marketing chick” or there with a boyfriend.

Under no circumstances should you ask a woman to prove her technical knowledge to you (even in jest).

Additionally, there’s a lot of implicit misogyny when you feign surprise upon discovering that a conventionally-attractive or feminine-presenting woman is also a geek. If you tell a woman approvingly that she’s “one of the guys” or “not like other women”, well, I’m gonna go out on a limb and say you’ve got some assumptions you need to rethink. (And I’m saying that as a woman who was proud to be called both of those things at one point.)

So, don’t say something like “Wow, I would never guessed you were a nerd!” Technical women often have to walk a fine line between looking properly “nerdy” (at the risk of coming across as sloppy) and looking put-together (but risking being taken less seriously).

7. Fetishizing “hot geek girls”.

It’s not a compliment to get comments like “Wow, a beautiful woman who’s also into kernel hacking?? Will you marry me?”

Rule of thumb: Don’t say anything you wouldn’t say to a man! It’s disrespectful to focus on someone’s appearance instead of their accomplishments.

The “fake marriage proposal” is extra weird because it’s grounded in a measure of success predicated on one’s desirability as a sexual or romantic partner. Women are people in their own right and have value independent of their relationships to men. A radical idea, I know.

An unsolicited “I find you attractive!” remark isn’t a compliment, it’s a note from a boner. I think it’s pretty safe to say that the vast majority of women in technical careers didn’t get into them in order to serve as eye candy or find a date.

We don’t want to be singled out and given extra attention because “ooooh, a woman!”. Yes, being a woman in tech has its unique challenges, but no one wants to feel like they’re only getting attention because of their gender. We want to be treated normally, like human beings who happen to share some perfectly ordinary and normal interests with you.

8. Denigrating things by comparing them to women or femininity.

Don’t casually accuse someone of being “girly” or a “pussy”, or say that they “fight like a girl”, or make fun of them for liking “chick flicks”. Stop policing masculinity with comments about men who cross the line into “too feminine”.

Be on guard for unnecessarily-gendered terms (hysterical, shrill, “man up”, “grow a pair”, ballsy). Notice how those examples are all predicated on the assumption that acting like a man is inherently good, and acting like a woman is inherently bad?

Those are some of the most overt ones, but this kind of thing is weirdly common. I recently called out a cyclist friend for referring to the lowest gear as the “granny gear”.

9. Stereotyping women’s needs… or ignoring them.

Emery boards as conference swag? Really? Protip: Women use battery packs and stickers too.

Conversely, many apps just outright ignore features that disproportionately affect female users (like the conspicuous absence of period tracking functionality in the Apple’s new Health app). The whole issue of swag t-shirts is a big one in this category.

Which brings us neatly to…

10. Using dark UI patterns.

If you write software that enables harassment and stalking, or makes it difficult for users to protect their personal information, you’re disproportionately driving women off of your platform or making them do extra work. Respecting user’s privacy and emphasizing consent in software design is fundamentally an issue of equality — not just gender, but across the board.

Watch out for requirements, such as “real name” policies, that unfairly impact marginalized groups. Commit to writing software that embodies affirmative consent.

11. Repeating generalizations about gender essentialism.

“Women just aren’t interested in programming/math/logic.” This is a thing that people really think, and say out loud. Statistically, the variation between individuals dwarfs any biological differences, and perpetuating these stereotypes has a real, harmful effect.

Even complimentary stereotypes, like “women are better at communicating” or “women have a better eye for design” contribute to the problem by encouraging a “men are from Mars, women are from Venus” approach to gender. This is also known as benevolent sexism.

Similarly, don’t reduce the gender gap in tech to a problem of “getting more women into the pipeline”. The reality is that women leave the industry at every stage of their careers. Solving the pipeline problem is necessary, but not a magic bullet.

On the flip side, don’t excuse bad behavior with “boys will be boys” type excuses. Dismantling gender stereotypes is also about having more respect for men — believing they are just as capable of empathy and self-restraint as any other adult human being.

12. Assuming every woman in tech feels the same way and/or wants to discuss her experiences “as a woman in tech”.

We’re not a monolith, we can’t all speak for each other, and we often want to just talk about our work instead of being seen as women first. See the Ada Initiative’s great post, Breaking The Unicorn Law.

13. Staying quiet when other men do these things.

Finally: this is everybody’s work. It’s not just the responsibility of those affected to speak up — we all play a part in setting the standards for the communities we’re a part of. Leigh Honeywell has a great post about how each of us can help, in the infosec world or anywhere else:

We aren’t doomed to being the harassment and sexual assault capital of the tech world. We can make a difference. And it starts with each one of us standing up for what we think is right, in the moment when it happens.

The concept of “privilege” seems to often come across as an insult, but I think it’s also a statement that you have power in a particular situation, and it’s possible to use that power for good. Those with more privilege have the power to amplify the voices of others, to challenge the status quo without fearing the consequences of speaking up.


Anyhow, that’s what I’ve got. These things serve as a starting point, an MVP, if you will. It’s certainly possible to do more, if you’re willing to devote the time and energy, but these suggestions are the “low-hanging fruit”: small, simple changes that will build the foundation for a better tech culture.

Other great posts along these lines:

Thoughts? Please comment or tweet at me! You can also check out my saved links on Pinboard (basically a firehose of everything I read online).

Like this:

Like Loading...

This entry was tagged feminism. Bookmark the permalink.

Las cosas chiquitas que cambian el mundo

Nota

Tengo dos weblogs. Este es en el que escribo artículos técnicos o que tienen que ver de alguna manera con mi profesión. Textos y pretextos es igual de personal, pero me sale —me sale cada vez menos, tristemente— de otras tripas, quizás para otro público.

Sin embargo, quiero hacer una excepción con este post, porque probablemente tenga más alcance aquí y es algo que me atraviesa todas las facetas: las ganas de hacer de este que pisamos, un mejor mundo.

Desde el 2005, a las poquitas semanas de haberme venido a vivir a Córdoba, hasta no sé que día del 2012, cada sábado de todas las semanas del año, me tomé dos bondis (o uno, cuando me iba a pata hasta el centro), para llegar a Campo de La Ribera. Mazamorra, la agrupación, fue mi espacio de militancia, mi usina de amistad, mi cobijo del dar y recibir. Sobre todo del recibir.

Leer más…