From Sinfronteras
Jump to: navigation, search


Online Python Interpreters

These ones supports many languages:


Installing python on Ubuntu

The last version of Python is usually installed this way. It can be verified in many sources:

sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.8

python --version

Installing Anaconda

Display the installed version

Para ver la versión por defecto:

python --version

O simplemente entrando a la línea de comandos python a través de:


Ahora, en un SO pueden haber más de una versión instalada. Para ver que versiones de python se encuentran ya instaladas en nuestro sistema operativo podemos ir al directorio /usr/bin y ver que ejecutables de python se encuentran:

ls /usr/bin/python
python      python2     python2.7   python3     python3.5   python3.5m  python3m    pythontex   pythontex3

y para ver la versión exacta (Python 3.5.2) ejecutamos python3.5 y este nos muestra la versión exacta al entrar a la línea de comandos python:

Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.

Change the default version

Change python version on per user basis

To change a python version on per user basis you simply create an alias within user's home directory. Open ~/.bashrc file and add new alias to change your default python executable:

alias python='/usr/bin/python3.4'

Once you make the above change, re-login or source your .bashrc file:

. ~/.bashrc

Change python version system-wide

To change python version system-wide we can use update-alternatives command.

Logged in as a root user. First we can list all available python alternatives:

# update-alternatives --list python
update-alternatives: error: no alternatives for python

El comando anterio debería mostrar las alternativas (por ejemplo python2.7 , python3.5) que ya han sido incluidas a través del comando update-alternatives --install. The above error message means that no python alternatives has been recognized by update-alternatives command. For this reason we need to update our alternatives table and include both python2.7 and python3.5:

Debemos entonces contruir la tabla de alternativas de la siguiente forma:

# update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
update-alternatives: using /usr/bin/python2.7 to provide /usr/bin/python (python) in auto mode
# update-alternatives --install /usr/bin/python python /usr/bin/python3.5 2
update-alternatives: using /usr/bin/python3.4 to provide /usr/bin/python (python) in auto mode

The --install option take multiple arguments from which it will be able to create a symbolic link. The last argument specified it priority means, if no manual alternative selection is made the alternative with the highest priority number will be set. In our case we have set a priority 2 for /usr/bin/python3.4 and as a result the /usr/bin/python3.5 was set as default python version automatically by update-alternatives command.

Es decir, si queremos que python2.7 sea la versión por defecto podemos ejecutar el comando update-alternatives --intall de la forma mostrada arriba y ajustar el último argumento de forma tal que el mayor valor sea asociado a la versión que queremos por defecto.

IDE for Python


This is not an IDE but an extension that can be installed in many IDEs.

Kite is the autocomplete developers trust to improve their productivity. Fully local and powered by machine learning.



Visual Studio Code

Python in Visual Studio Code


Sublime Text

Sublime Text is a proprietary cross-platform source code editor with a Python application programming interface (API). It natively supports many programming languages and markup languages, and functions can be added by users with plugins.


wget -qO - | sudo apt-key add -
sudo apt-add-repository "deb apt/stable/"
sudo apt install sublime-text

Keyboard shortcut to comment lines in Sublime Text 3

As a workaround, go to Preferences->Key Bindings - User and add these keybindings (if you're using Linux):

{ "keys": ["ctrl+7"], "command": "toggle_comment", "args": { "block": false } },
{ "keys": ["ctrl+shift+7"], "command": "toggle_comment", "args": { "block": true } }


If you want it for all files, go to Preferences -> Settings - Default/User. But as several comments below indicate, Syntax Specific settings can limit it to just the languages you choose.

To limit this configuration to Ruby files, first open up a Ruby file in the editor, and then go to Preferences -> Settings -> More -> Syntax Specific -> User. This should open a settings window named Ruby.sublime-settings

Save these settings:

  "tab_size": 2,
  "translate_tabs_to_spaces": true,
  "detect_indentation": false

Crear un proyecto en Sublime Text

  1. Abrimos una nueva ventana: File > New Window
  2. Add folder to project
  3. Save project as: es apropiado guardarlo en el mismo directorio en donde fue creado el proyecto.

Esto creará dos archivos:

  • nombre-111.sublime-project
  • nombre-111.sublime-workspace : Este es el que debemos abrir para ingresar al proyecto.



Using umake

De esta forma lo instalé correctamente:

sudo add-apt-repository ppa:ubuntu-desktop/ubuntu-make
sudo apt-get update
sudo apt-get install ubuntu-make

Once you have umake, use the command below to install PyCharm Community Edition in Ubuntu:

umake ide pycharm

Se instaló en la siguiente ruta:


Using Snap

De esta forma lo instalé correctamente:

sudo snap install pycharm-community --classic

Sin embargo, luego de instalarlo de esta manera, cuando iniciaba pycharm, se creaba automáticamente el directorio /home/adelo/snap. Traté de cambiar la ubicación de este directorio y no di con la solución.

Python on eclipse

Para utilizar Python en Eclipse debemos instalar PyDev:

Help > Eclipse Marketplace Find: PyDev

Using Python

Python Shell

From the terminal, you can start the Python Shell/Interpreter (Also know as Python Interactive Shell) using the command:


Premiers pas avec l interpreteur de commandes Python

Operations courantes
>>> 3 + 4
>>> 9.5 + 2
>>> 3.11 + 2.08

Writing and Running a Python code

You can use your favorite Text Editor or IDE to write your Python code:

c=input("Ingrese un caracter: ")
e=int(input("Entrez un entier: "))

for i in range(1,e+1):
	for j in range(1,i+1):

  • If we use the line #!/usr/bin/python3.6 to indicate the path to the Python Interpreter, then we can then run our code as a Executable file this way:

  • However, the most common way is not including #!/usr/bin/python3.6 and calling the Python Interpreter through the python command:

  • Of course, you can also run a Python program through a button on a IDE Graphical Interface.

pip and virtualenv

pip  install librarie
pip3 install librarie

Para especificar la versión de python a la cual será instalada la libreria:

python3 -m pip install pandas

En este caso, cuando usemos python3 «pandas» estará disponible, pero no necesariamente para otras versiones de python

How can I install packages using pip according to the requirements.txt

pip install -r requirements.txt
python3.8 -m pip install -r requirements.txt

Crear un virtualenv:

virtualenv myproject_env  # This will install a local copy of Python and pip into a directory called myprojectenv

Activar el virtualenv:

source myproject_env/bin/activate

Para especificar la versión de Python que del virtualenv:

virtualenv -p python3.8 myproject_env    # Creates a new default python3.8 (python3.8 must be a valid command i.e found in the PATH)

Para salir del virtualenv:

(myproject_env)$ deactivate

Data types


In this source you can find a very good documentation about Python Data Types and the most important Operations and Methods for each Data Type:

Numbers Integers Plain integers
Long integers
Floating point numbers
Complex numbers
Sequences Immutable sequences Strings
Mutable sequences Lists
Mappings Dictionaries
Callable types User-defined functions
User-defined methods
Built-in functions
Built-in methods
Class instances
Class instances
Internal types Code objects
Frame objects
Traceback objects
Slice objects

Getting the Data Type: You can get the data type of any object by using the type() function:

Type/Class Description Example Setting the Specific Data Type Operations/Functions/Methods
Numeric Types int Int, or integer, is a whole number, positive or negative, without decimals, of unlimited length. x = 20 x = int(20)
float Float, or "floating point number" is a number, positive or negative, containing one or more decimals. x = 20.5 x = float(20.5)
complex Complex numbers are written with a "j" as the imaginary part x = 1j x = complex(1j)
Text Type str Strings are Arrays: Like many other popular programming languages, strings in Python are arrays of bytes representing unicode characters. However, Python does not have a character data type, a single character is simply a string with a length of 1. x = "Hello World" x = str("Hello World")
Boolean Type bool Booleans represent one of two values: True or False. x = True x = bool(5)
Binary Types bytes x = b"Hello" x = bytes(5)
bytearray x = bytearray(5) x = bytearray(5)
memoryview x = memoryview(bytes(5)) x = memoryview(bytes(5))
Python Collections (Arrays) Sequence Types list A list is a collection which is ordered and changeable. x = ["apple", "banana", "cherry"] x = list(("apple", "banana", "cherry"))

Nice way to create a list:
lista = [x**2 for x in range(12) if x%3 == 0]
# Output:
[0, 9, 36, 81]

tuple A tuple is a collection which is ordered and unchangeable. x = ("apple", "banana", "cherry") x = tuple(("apple", "banana", "cherry"))
Array Python does not have built-in support for Arrays. You have to import it from a Library:

from numpy import array

x = array([3, 6, 9, 12])

There are some differences between Array and List:

Lists are containers for elements having differing data types but arrays are used as containers for elements of the same data type.

Arrays are specially optimised for arithmetic computations, Ex:

x = array([3, 6, 9, 12])

divided_x = x/2 # This would return an error if using List


[1.5 3. 4.5 6. ]

range x = range(6) x = range(6)
Mapping Type dict A dictionary is a collection which is unordered, changeable and indexed. In Python dictionaries are written with curly brackets, and they have keys and values. x = {"name" : "John", "age" : 36} x = dict(name="John", age=36)
Set Types set A set is a collection which is unordered and unindexed. x = {"apple", "banana", "cherry"} x = set(("apple", "banana", "cherry"))
frozenset x = frozenset({"apple", "banana", "cherry"}) x = frozenset(("apple", "banana", "cherry"))


Operator Name/Description Example Same as


Java JS R Python Java F R
Arithmetic Operators + + Addition x + y
- - Subtraction x - y
* * Multiplication x * y
/ / Division x / y
% % Modulus x % y
** java.util.Math Exponentiation x ** y import java.util.Math

Double result = Math.pow(number, exponent);

// Floor division x // y
++ Increment: Increases the value of a variable by 1 ++x
-- Decrement: Decreases the value of a variable by 1 --x
Assignment Operators = = x = 5
+= += x+= 3 x = x + 3
-= -= x -= 3 x = x - 3
*= *= x *= 3 x = x * 3
/= /= x /= 3 x = x / 3
%= %= x %= 3 x = x % 3
//= x //= 3 x = x // 3
**= x **= 3 x = x ** 3
&= &= x &= 3 x = x & 3
|= |= x |= 3 x = x | 3
^= ^= x ^= 3 x = x ^ 3
>>= >>= x >>= 3 x = x >> 3
<<= <<= x <<= 3 x = x << 3
Comparison Operators == == Equal x == y
!= != Not equal x != y
> > Greater than x > y
< < Less than x < y
>= >= Greater than or equal to x >= y
<= <= Less than or equal to x <= y
Logical Operators and && Logical and: Returns True if both statements are true x < 5 and x < 10 x < 5 && x < 10
or || Logical or: Returns True if one of the statements is true x < 5 or x < 4 x < 5 || x < 4
not ! Logical not: Reverse the result, returns False if the result is true not(x < 5 and x < 10) !(x < 5 && x < 10)
Identity Operators is Returns true if both variables are the same object x is y
is not Returns true if both variables are not the same object x is not y
Membership Operators in Returns True if a sequence with the specified value is present in the object x in y
not in Returns True if a sequence with the specified value is not present in the object x not in y
Bitwise Operators &

Sets each bit to 1 if both bits are 1

| OR

Sets each bit to 1 if one of two bits is 1


Sets each bit to 1 if only one of two bits is 1


Inverts all the bits

<< Zero fill left shift

Shift left by pushing zeros in from the right and let the leftmost bits fall off

>> Signed right shift

Shift right by pushing copies of the leftmost bit in from the left, and let the rightmost bits fall off

Added by myself
String concatenation +
"Coucou ' + 'c\'est ' + 'nous !";
'Coucou '.concat('c\'est ', 'nous !');
['Coucou ', 'c\'est ', 'nous !'].join();

Control flow statements

If statements

a = 200
b = 33
if b > a:
     print("b is greater than a")
elif a == b:
     print("a and b are equal")
     print("a is greater than b")

Short Hand If:

 if a > b: print("a is greater than b")

One line if else statement, with 3 conditions:

print("A") if a > b else print("=") if a == b else print("B")

For Loops

Print each fruit in a fruit list:

fruits = ["apple", "banana", "cherry"]
for fruit in fruits:

# Output:

fruits = ["apple", "banana", "cherry"]
for fruit_no, fruit in enumerate(fruits):
     print(fruit_no, fruit)

# Output:
0 apple
1 banana
2 cherry

Looping Through a String:

for x in "banana":

The break Statement:

fruits = ["apple", "banana", "cherry"]
for x in fruits:
     if x == "banana":

The continue Statement: With the continue statement we can stop the current iteration of the loop, and continue with the next:

fruits = ["apple", "banana", "cherry"]
for x in fruits:
     if x == "banana":

The range() Function: The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and ends at a specified number.

for x in range(6):

Note that range(6) is not the values of 0 to 6, but the values 0 to 5.

The range() Function: The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and ends at a specified number.

for x in range(2, 30, 3):

While Loops

i = 1
while i < 6:
     i += 1

The break Statement:

i = 1
while i < 6:
     if i == 3:
     i += 1

The continue Statement: With the continue statement we can stop the current iteration, and continue with the next:

i = 0
while i < 6:
     i += 1
     if i == 3:

The else Statement: With the else statement we can run a block of code once when the condition no longer is true:

i = 1
while i < 6:
  i += 1
  print("i is no longer less than 6")

Input and Output

Input and Output funtions: Esta página creo que no está actualizada para python 3, pero está bien organizada:


name = input("What's your name? ")
print("Nice to meet you " + name + "!")
age = input("Your age? ")
print("So, you are already " + age + " years old, " + name + "!")

La función input asigna por defecto una variable de tipo str. Si queremos que la variable sea tipo int o list:

>>> population = int(input("Population of Toronto? "))
Population of Toronto? 2615069
>>> print(population, type(population))
2615069 <class 'int'>
>>> cities_canada = eval(input("Largest cities in Canada: "))
Largest cities in Canada: ["Toronto", "Montreal", "Calgara", "Ottawa"]
>>> print(cities_canada, type(cities_canada))
['Toronto', 'Montreal', 'Calgara', 'Ottawa'] <class 'list'>



The print() function prints the specified message to the screen, or other standard output device:

print("Hello World")

The full syntax of print() is:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

Print more than one object:

a = 5
b = a

print('a =', a, '= b')

print() with separator and end parameters:

a = 5
print("a =", a, sep='00000', end='\n\n\n')
print("a =", a, sep='0', end='')

Print a tuple:

x = ("apple", "banana", "cherry")

The String format() Method

Basic usage of the str.format() method looks like this:

print('{0} and {1}'.format('spam', 'eggs'))

Positional and keyword arguments can be arbitrarily combined. It is better to use keyword arguments because it is less likely to make mistake because of the position of the arguments.

print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', other='Georg'))

Functions and Methods

How to define a Function

def hello():

def area(width, height):
    return width * height

def print_welcome(name):
    print("Welcome", name)


w = 4
h = 5
print("width =", w, " height =", h, " area =", area(w, h))

def factorial():
        n=int(input("Entrez un entier positif: "))
        for i in range(n,1,-1):


Some important Functions and Methods


type()returns the type of these objects:

a = ('apple', 'banana', 'cherry')
b = "Hello World"
c = 33

x = type(a)
y = type(b)
z = type(c)

List of Functions and Methods

What’s the difference between Python functions and methods?:

After reading this far in the article, I bet you have this question: “Why on Earth do we have both functions and methods, when they practically do the same thing?”

I remember that when I started learning Python, I had a hard time answering this question. This is still the most confusing topic for newcomers in the Python-world.

The official answer is that there is a small difference between them. Namely: a method always belongs to an object (e.g. in the dog.append(4) method .append() needed the dog object to be applicable), while a function doesn’t necessarily. To make this answer even more twisted: a method is in fact nothing else but a specific function. Got it? All methods are functions, but not all functions are methods! Function/Method Description Example
Built-in functions

abs() Returns the absolute value of a numeric value abs(-4/3)
round() Returns the rounded value of a numeric value. round(-4/3)
min() Returns the smallest item of a list or of the typed-in arguments. It can even be a string. min(3,2,5)


sorted() It sorts a list into ascending order. The list can contain strings or numbers. a = [3, 2, 1]sorted(a)
sum() It sums a list. a = [3, 2, 1]sum(a)
len() Returns the number of elements in a list or the number of characters in a string. len('Hello!')
String methods

a.lower() Returns the lowercase version of a string. a = 'MuG'a.lower()
a.strip() If the string has whitespaces at the beginning or at the end, it removes them. a = ' Mug 'a.strip()
a.replace('old', 'new') Replaces a given string with another string. Note that it’s case sensitive. a = 'muh'a.replace('h','g')
a.split('delimiter') Splits your string into a list. Your argument specifies the delimiter. a = 'Hello World'a.split(' ')
'delimiter'.join(a) It joins elements of a list into one string. You can specify the delimiter again. a = ['Hello', 'World']

' '.join(a)

List methods

a.append(arg) Adds an element to the end of our list. dog = ['Freddie', 9, True, 1.1, 2001, ['bone', 'little ball']]


a.remove(arg) We have to specify the element that we want to remove and Python will remove the first item with that value from the list. dog.remove(2001)
a.count(arg) Returns the number of the specified value in a list. dog.count('Freddie')
a.clear() removes all elements of the list. It will basically delete Freddie. No worries, we will get him back. dog.clear()
Dictionaries methods

a.keys() It returns all the keys from your dictionary.
dog_dict.values() It returns all the values from your dictionary.
dog_dict.clear() It deletes everything from your dictionary.
Tuple methods

Set methods

File methods


while True:
         x = int(raw_input("Please enter a number: "))
     except ValueError:
         print "Oops!  That was no valid number.  Try again..."

OOP with Python

The self

Class methods have only one specific difference from ordinary functions - they must have an extra first parameter that has to be added to the beginning of the parameter list, but you do not give a value for this parameter when you call the method, Python will provide it. This particular variable refers to the object itself, and by convention, it is given the name self.

Say you have a class called MyClass and an instance of this class called myobject. When you call a method of this object as myobject.method(arg1, arg2), this is automatically converted by Python into MyClass.method(myobject, arg1, arg2) - this is all the special self is about.

This also means that if you have a method which takes no arguments, then you still have to have one argument - the self.

class Person:
    def say_hi(self):
        print('Hello, how are you?')

p = Person()
# The previous 2 lines can also be written as
# Person().say_hi()

The __init__ method

There are many method names which have special significance in Python classes. We will see the significance of the __init__ method now.

The __init__ method is run as soon as an object of a class is instantiated. The method is useful to do any initialization you want to do with your object. Notice the double underscores both at the beginning and at the end of the name.

Example (save as

class Person:
    def __init__(self, name): = name

    def say_hi(self):
        print('Hello, my name is',

p = Person('Swaroop')
# The previous 2 lines can also be written as
# Person('Swaroop').say_hi()
$ python
Hello, my name is Swaroop

Class And Object Variables

En el siguiente ejemplo, population belongs to the Robot class and hence is a class variable. The name variable belongs to the object (it is assigned using self) and hence is an object variable.

Thus, we refer to the population class variable as Robot.population and not as self.population. We refer to the object variable name using notation in the methods of that object.

Instead of Robot.population, we could have also used self.__class__.population because every object refers to its class via the self.__class__ attribute

Object variables are owned by each individual object/instance of the class. In this case, each object has its own copy of the field i.e. they are not shared and are not related in any way to the field by the same name in a different instance. An example will make this easy to understand (save as

Class methods

The how_many method difined in the next example is actually a method that belongs to the class and not to the object. This means we can define it as either a classmethod or a staticmethod depending on whether we need to know which class we are part of. Since we refer to a class variable, let's use classmethod.

We have marked the how_many method as a class method using the classmethod decorator.

Decorators can be imagined to be a shortcut to calling a wrapper function, so applying the @classmethod decorator is same as calling:

how_many = classmethod(how_many)


In this program, we also see the use of docstrings for classes as well as methods. We can access the class docstring at runtime using Robot.__doc__ and the method docstring as Robot.say_hi.__doc__


class Robot:
    # Docstrings
    """Represents a robot, with a name."""

    # A class variable, counting the number of robots
    population = 0

    def __init__(self, name):
        # Docstrings
        """Initializes the data.""" = name
        print("(Initializing {})".format(

        # When this person is created, the robot
        # adds to the population
        Robot.population += 1

    def die(self):
        """I am dying."""
        print("{} is being destroyed!".format(

        Robot.population -= 1

        if Robot.population == 0:
            print("{} was the last one.".format(
            print("There are still {:d} robots working.".format(Robot.population))

    def say_hi(self):
        """Greeting by the robot.

        Yeah, they can do that."""
        print("Greetings, my masters call me {}.".format(

    def how_many(cls):
        """Prints the current population."""
        print("We have {:d} robots.".format(cls.population))

droid1 = Robot("R2-D2")

droid2 = Robot("C-3PO")

print("\nRobots can do some work here.\n")

print("Robots have finished their work. So let's destroy them.")


$ python
(Initializing R2-D2)
Greetings, my masters call me R2-D2.
We have 1 robots.
(Initializing C-3PO)
Greetings, my masters call me C-3PO.
We have 2 robots.

Robots can do some work here.

Robots have finished their work. So let's destroy them.
R2-D2 is being destroyed!
There are still 1 robots working.
C-3PO is being destroyed!
C-3PO was the last one.
We have 0 robots.


The SchoolMember class in this situation is known as the base class or the superclass. The Teacher and Student classes are called the derived classes or subclasses.

We will now see this example as a program (save as

class SchoolMember:
    '''Represents any school member.'''
    def __init__(self, name, age): = name
        self.age = age
        print('(Initialized SchoolMember: {})'.format(

    def tell(self):
        '''Tell my details.'''
        print('Name:"{}" Age:"{}"'.format(, self.age), end=" ")

class Teacher(SchoolMember):
    '''Represents a teacher.'''
    def __init__(self, name, age, salary):
        SchoolMember.__init__(self, name, age)
        self.salary = salary
        print('(Initialized Teacher: {})'.format(

    def tell(self):
        print('Salary: "{:d}"'.format(self.salary))

class Student(SchoolMember):
    '''Represents a student.'''
    def __init__(self, name, age, marks):
        SchoolMember.__init__(self, name, age)
        self.marks = marks
        print('(Initialized Student: {})'.format(

    def tell(self):
        print('Marks: "{:d}"'.format(self.marks))

t = Teacher('Mrs. Shrividya', 40, 30000)
s = Student('Swaroop', 25, 75)

# prints a blank line

members = [t, s]
for member in members:
    # Works for both Teachers and Students

$ python
(Initialized SchoolMember: Mrs. Shrividya)
(Initialized Teacher: Mrs. Shrividya)
(Initialized SchoolMember: Swaroop)
(Initialized Student: Swaroop)

Name:"Mrs. Shrividya" Age:"40" Salary: "30000"
Name:"Swaroop" Age:"25" Marks: "75"

Some example codes

Factorial function using recursion

A VERY VERY NICE example of recursion is the factorial function:

4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1
Replacing the calculated values gives us the following expression
4! = 4 * 3 * 2 * 1

def factorial(n):
    if n == 1:
        return 1
        return n * factorial(n-1)

Python for Data Science

Python Web Development

Web Frameworks for Python:

Ejemplos de Web Applications in Python:

Complete Python Web Course (15€):



Página oficial:


Deploy a Django application with Nginx and Gunicorn

Este tutorial explica bastante bien como realizar el deployment:

Basta con seguir el tutorial detalladamente para realizar el deployment. Estos son los puntos en los cuales me tranqué la última vez:

  • Es importante definir adecuadamente estas variables en el
import os

ALLOWED_HOSTS = ['', 'localhost', '']

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

  • Este paso al parecer tiene que ser realizado en el servidor (no antes) no lo comprobé que sea cierto pero lo leí:
./ collectstatic

En mi caso tuve que hacerlo así:

python collectstatic

  • Pra Test the Django Development Server:
./ runserver

tuve que hacerlo así:
python runserver

  • Este paso también me causó problemas. Hay que hacerlo luego de «python collectstatic» porque sino los archivos generados en dicho paso no tendrán la permisología adecuada:
chown -R www-data:root ~/django_project

  • También es muy importante notar que siempre que se realicen cambios en los arechivos de gunicorn «.service» o «.socket» hay que «restart» el «gunicorn.socket». La vez anterior estaba haciend «systemctl start gunicorn.socket» en lugar de «restart» y los cambios no estaban guardando. Hay que realizar todos estos pasos para estar seguros que los cambios han tomado efecto:
systemctl daemon-reload

systemctl restart gunicorn.socket
systemctl start gunicorn.socket
systemctl enable gunicorn.socket

systemctl status gunicorn.socket

systemctl restart nginx

sudo tail -30 /var/log/nginx/error.log