My First Dive into Python as a Javascript and Java Programmer

Nyef
Nyef
·
My First Dive into Python as a Javascript and Java Programmer

In this blog post, I share my findings from diving into Python as a freelance Java(script) developer. As a software developer, it's important to continuously learn and keep up with both new and existing techniques.

In the software world, new techniques are being developed at a rapid pace. But sometimes, there's also a rising demand for existing, older techniques like Python.

Looking at Google Trends in the Netherlands over the past few years, you can see a decent increase for the search term " Python." Lately, I've also had the feeling that the number of Python assignments is growing, judging by the (permanent and freelance) assignments that come my way.

Python rising in Google Trends Netherlands

Furthermore, I don't just think it's important to continuously learn new techniques and gain experience, but I also genuinely enjoy it.

As mentioned earlier, in this blog post, I'll outline what stands out to me or what's new to me about Python, compared to Javascript (ES6) and Java, which I work with a lot.

1. NumPy

Although it's a third-party library, I'd still like to highlight the power of NumPy.

NumPy is an open source project that enables numerical computing with Python. (numpy.org)

What I find particularly interesting is how easily you can perform a calculation on every element in a NumPy array. For example:

Python

1import numpy as np
2
3# Een numpy array maken
4arr = np.array([1, 2, 3, 4, 5])
5
6# Een operatie uitvoeren op alle elementen
7result = arr * 2
8
9print(result)  # Output: [ 2  4  6  8 10]

On line 7, you see how simple it is to multiply all elements: arr * 2. If you wanted to filter arr for elements greater than or equal to 3, you'd simply do: arr[arr >= 3]. Handy, right? And that's just the beginning of NumPy!

2. Reading Files with Python

Every now and then, I write a Node.js script to read a file and do something with it. For this, I use the fs module:

JavaScript

1const fs = require('fs');
2
3const fileName = 'example.txt';
4fs.readFile(fileName, 'utf8', (err, data) => {
5    if (err) {
6        console.error('Error reading file:', err);
7        return;
8    }
9
10    console.log(data);
11});

To do the equivalent in Python, you can use the open function in combination with a with statement. That with statement, by the way, reminds me of Java's try-with-resources block:

Python

1with open('example.txt', 'r') as f:
2    contents = f.read()
3
4print(contents)

3. Data Analysis with Pandas

A few years ago, for an assignment, I had to perform some data analyses based on data from various CSV files. For that, I created a script with Node.js & NPM. To efficiently read and iterate over all the rows, I had to use an external NPM library. All in all, I had to write relatively a lot of code compared to Pandas! (Note: There are NPM libraries inspired by or based on Pandas, or equally efficient ones, but I'll ignore those for now.)

pandas is a fast, powerful, flexible and easy to use open source data analysis and manipulation tool, built on top of the Python programming language. (pandas.pydata.org)

Suppose I have the following CSV file people.csv with names and ages of people:

| Name    | Age |
|---------|-----|
| John    | 25  |
| Emma    | 30  |
| Michael | 22  |
| Sophia  | 28  |
| William | 35  |

If I want to filter all people with an age >= 30, I can do that with just a few lines of code:

Python

1import pandas as pd
2
3df = pd.read_csv('people.csv')
4filtered = df[df['Age'] >= 30]
5print(filtered)
6
7# Output:
8# Name  Age
9# 1     Emma   30
10# 4  William   35

Super easy! Of course, Pandas can do much more, and I'll definitely experiment with it further.

4. List Comprehensions

List Comprehensions is a very powerful tool, which creates a new list based on another list, in a single, readable line. (learnpython.org)

With list comprehensions, you can create, transform, and filter a list in a single line. In ES6, I'd do that using .map() or .filter(). Python has these too, but in the Python world, list comprehensions are preferred.

Suppose I have a Person class with name and age properties, then I can filter a list of them (lines 10-16) by age (line 19) and print it using list comprehensions (line 22):

Python

1class Person:
2    def __init__(self, name, age):
3        self.name = name
4        self.age = age
5
6    def __str__(self):
7        return self.name + "=" + str(self.age)
8
9
10people = [
11    Person("John", 25),
12    Person("Emma", 30),
13    Person("Michael", 22),
14    Person("Sophia", 28),
15    Person("William", 35)
16]
17
18# Filter with list comprehension
19filtered = [person for person in people if person.age >= 30]
20
21# Print with list comprehension
22print([str(person) for person in filtered])
23
24# Output:
25# ['Emma=30', 'William=35']

5. Lambda Functions in Python

When lambda functions came up in one of the online tutorials I was following, I had flashbacks to my university days. There, I took the Functional Programming course where we learned to program with Haskell. And that's what Python's lambda syntax reminded me of; it looks like this:

Python

1sum = lambda x, y: x + y
2
3print(sum(3, 4))  # Output: 7

You explicitly need to use the lambda keyword here. With ES6, that's not necessary, and you'd simply do:

JavaScript

1(x, y) => x + y

6. Function Arguments by Keywords

Every now and then, it's useful to specify function parameters by name. For example, with Javascript, if you want to prevent your code from breaking if the parameter order changes for whatever reason, you can use object destructuring:

JavaScript

1const divide = ({a, b}) => a / b;
2divide({b: 2, a: 10}); // Output: 5

In the example above, I explicitly specify what the values of a and b should be when calling divide.

The same works more easily in Python — object destructuring isn't necessary. Here's the principle of function arguments by keywords in Python:

Python

1def divide(a, b):
2    return a / b
3
4
5divide(b=2, a=10)  # Output: 5.0

7. Variable Scopes

The global Keyword (Python vs. Javascript)

If you want to use a global variable, defined outside a function, within a Python function, you need to use the global keyword.

In the following Python code block, you see the variable my_num = 10. Then, in myfunction, a value of 12 is assigned to my_num. However, my_num inside myfunction is a new variable. So, the output shows two different values:

Python

1my_num = 10
2
3
4def myfunction():
5    my_num = 12
6    print(my_num)
7
8
9myfunction()
10print(my_num)
11
12# Output:
13# 12
14# 10

If you want myfunction to assign the value to the global variable, you need to indicate in the function that you're using the global my_num with global my_num. In that case, the output changes:

Python

1my_num = 10
2
3
4def myfunction():
5    global my_num  # <- Difference
6    my_num = 12
7    print(my_num)
8
9
10myfunction()
11print(my_num)
12
13# Output:
14# 12
15# 12

Coming from the Java(script) world, this will take some getting used to for me. With Javascript, you define a new variable with var, const, or let. At that moment, you already know it's the first definition, unlike Python. So, you don't need to specify in a function that you want to use the global variable.

The previous example in Javascript would look like this:

JavaScript

1let my_num = 10;
2
3const myfunction = () => {
4    my_num = 12;
5    console.log(my_num);
6};
7
8myfunction();
9console.log(my_num);
10
11// Output:
12// 12
13// 12

In this case, myfunction directly uses the global my_num.

The nonlocal Keyword

Another thing that'll take some getting used to for me: nonlocal. With nonlocal, you specify within a nested function that the variable from the enclosing function should be used.

In the following example, you see the outer function with a nested inner function. The output is, again, different:

Python

1def outer():
2    my_num = 10
3
4    def inner():
5        my_num = 12
6        print(my_num)
7
8    inner()
9    print(my_num)
10
11
12outer()
13
14# Output:
15# 12
16# 10

If you now specify in inner that inner should use the my_num from the enclosing function, the output will differ:

Python

1def outer():
2    my_num = 10
3
4    def inner():
5        nonlocal my_num  # <- Difference
6        my_num = 12
7        print(my_num)
8
9    inner()
10    print(my_num)
11
12
13outer()
14
15# Output:
16# 12
17# 12

If you use nonlocal in the outer function, by the way, you'll get an error.

Conclusion

Although my Python knowledge is still relatively shallow, I've already learned a lot. For instance, I can now better understand why you might choose Python for data analysis over other languages.

In the coming time, I'll improve my Python knowledge. In the future, I'll definitely take on freelance Python assignments.

If you're looking for a good resource to learn Python, I recommend learnpython.org.

Share

Translation disclaimer: This blog post was originally written in Dutch and is translated to English. This translation may contain errors and can be inaccurate.

Need an experienced software engineer?

I help companies with software solutions (SaaS, automation and more) — from backend to frontend. Feel free to contact me to see how I can contribute to your project.

  • Robust backend: Java/Kotlin, SQL, Spring Framework
  • User-friendly front-end: Next.js, React, Typescript, ES6
  • Rapid development: Continuous integration & deployment, Jenkins
  • Efficient collaboration: Agile, Scrum, Jira, Git, Bitbucket, GitHub
  • Freelance software developer from Arnhem, The Netherlands