Click here to Skip to main content
15,888,527 members
Articles / Programming Languages / Python
Tip/Trick

My Questions to Python

Rate me:
Please Sign up or sign in to vote.
4.70/5 (5 votes)
27 Oct 2023CPOL3 min read 7.1K   4   9
Python became a quite popular programming/scripting language recently. But, after some inspiring experience, I've got some open questions...
I'm quite old to know that there are other languages more suitable for scripting, but I was asked to use more fancy (and less efficient) programming languages for scripting, because the new generation of developers doesn't even know about Perl and Shell scripting languages. I have to use Python to earn money and I'm not happy with this.

Introduction

Python is not a brand new programming language. It has got quite a long history of development. But it has still has got some unexplainable issues and I will try to reveal them within the article below.

Background

I was asked to use Python instead of Perl recently. I understand that Perl is still strong enough, but its development is a bit frozen. And it is strategically wise to switch to other languages with more active development to avoid dead end way. So, I don't really hate the modern programming languages, but I have to notice some issues that are making support process of the software created with these languages more difficult and exciting.

Using the Code

A code in the article contains the examples of the things that you must not do. Please don't use it at work and, of course, at home. Please avoid these example code patterns in the working code. The code has been written and "tested" with Python 3.11.

What Can You Catch From Python Code

Obvious Coding Issues

Here is an example of the text processing Python class:

Python
import sys
import platform
from io import TextIOWrapper

class FileReader:

    def __init__(self, inFileName: str, outFileName: str):
        plName = platform.system()
        if plName == 'Windows':
            self.isWindows = True
            self.newline = "\r\n"
        else:
            self.isWindows = False
            self.newline = "\n"
        if len(inFileName) < 1:
            self.stdin = TextIOWrapper(sys.stdin.buffer,
                                       newline="",
                                       encoding="utf-8")
        else:
            self.stdin = open(inFileName, "r", 1, encoding="utf-8")
        if len(outFileName) < 1:
            self.stdout = TextIOWrapper(sys.stdout.buffer,
                                        newline=self.newline,
                                        encoding="utf-8")
        else:
            self.stdout = open(outFileName, "w", 1, encoding="utf-8")
        self.someData = ''

    def getData(self) -> str:
        return self.someData

    def decodeSomeThing(self, txt: str, al1: list) -> str:
        atx = txt.split(',')
        al1[1] = '3'  # you will modify the value here and everywhere
        txt = atx[0]  # you will modify the local value here, but not outside
        return txt


fr = FileReader('','')
as1 = ['1','2']
s1 = 'some, things'
s2 = fr.decodeSomeThing(s1,as1)
print(s1,s2, as1)
print(fr.getData)

Please take a look at the last row of the code example above. I expected an error output like:

Terminal
AttributeError: 'FileReader' object has no attribute 'getData'

But there is not:

Terminal
some, things some ['1', '3']
<bound method FileReader.getData of <__main__.FileReader object at 0x7f950a5befd0>>

It is connected to the other language features, but it makes development and support process more exciting. :-)

Most of the things in Python will be passed by reference, but some are not. And you must learn it to make your code more predictable. Take a look at the rows with comments. Value of the s1 remains unchanged outside the function decodeSomeThing(), but the value of the as1 will be modified (see terminal example above).

Integer rounding "issue"

I was not expecting to see the integer rounding error issue below, but I saw it:

Python
#!/usr/bin/env python3
import sys


class MultiNumber:
    CHARSET64 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz, '
    CHARSET36 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'

    def __init__(self, charz: str = CHARSET64):
        self.charz = charz
        self.ord = len(self.charz)

    def encode(self, num: int) -> str:
        s1 = ''
        n1 = num
        while n1 > 0:
            n2 = int(n1 % self.ord)
            s1 = self.charz[n2] + s1
            n1 = int(n1 / self.ord)
        return s1

    def decode(self, snum: str) -> int:
        mul = 1
        n1 = 0
        i = len(snum) - 1
        while i >= 0:
            s1 = snum[i]
            ni = self.charz.find(s1)
            if ni > 0:
                n1 = n1 + (ni * mul)
            else:
                if ni < 0:
                    sys.stderr.write("Unable to decode character:'{0}' at pos {1}".format(s1, i))
                    break
            mul = mul * self.ord
            i = i - 1
        return n1


def main(argv):
    mn = MultiNumber(MultiNumber.CHARSET36)
    for arg in argv:
        n = int(arg)
        s1 = mn.encode(n)
        n1 = mn.decode(s1)
        print('{0:X} -> "{1}" -> {2}'.format(n, s1, n1))


if __name__ == "__main__":
    main(sys.argv[1:])

When I run the code above, I will receive the output:

Terminal
-bash $ ./multinumber.py 9223372036854775807
7FFFFFFFFFFFFFFF -> "1Y2P0IJ32E807" -> 9223372036854775303

The encoding result is not valid (proper result must be "1Y2P0IJ32E8E7"). And when I run the C implementation of the encoding:

C++
char* encode(int64_t n1, const char* charz)
{
    int64_t n2;
    static char s1[12];
    int64_t ord = strlen(charz);
    char* ptr = (s1 + sizeof(s1) - 1);
    char chr;
    *ptr = '\0';
    while (n1 > 0)  {
        n2 = n1 % ord;
        chr = charz[(size_t)n2];
        ptr --;
        *ptr = chr;
        n1 /= ord;
    }
    return ptr;
}
...
char* s1 = encode(9223372036854775807, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");

I receive a proper result.

Integer rounding "issue" explanation

As it was highlighted by Matthew Barnett in comments, my mistake was in syntax. That's not a rounding error as I thought. As from my previous experience with the other languages, mathematical operations are performed after all the operands are converted to the same type. And I was sure that Python does an implicit conversion to the result type for all the operands. But for integer division there is another operator (//) that I haven't noticed about. Well, I need to learn this lesson and my study for Python is far away from its end. Nobody is perfect, even if someone thinks so.

Points of Interest

I did not see anything exceptional with the issues highlighted in the article above. They are usual consequence of the programming languages development. I hope they will be fixed in the next releases. Or such a things have just highlighted more prominent in the documentation.

History

  • 25th October, 2023: First edition
  • 25th October, 2023: Second edition (some issue fixed)
  • 27th October, 2023: Logical mistake highlighted and explained (I hope so)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) NetCracker
Russian Federation Russian Federation
I came to the industry at the end of that times when the computer program executes as it was written. I saw a quite big machines, occupied more than 100 square meters for its central processor, but I started my professional activity as a programmer on IBM PC clones. There were different CPU architectures (68k, PowerPC, 386/486, SPARC...) when I began, but Intel defeated them all with Pentium CPU (marketing) family.
I saw the knowledge and technology fragmentation. I saw many technologies started, developed and retired. However, I have not seen many things yet.
I have some experience, but my experience is not perfectly comprehensive. I still have many things to learn and I still cannot make a poker face when I find out some aspects about how the things were designed and works. My experience does not make me an absolute expert in some areas, because these areas are changing. I know some things, but I also understand that some things I know could be useless for nowadays.

Comments and Discussions

 
QuestionEverything passed the same way Pin
Matthew Barnett30-Oct-23 5:47
Matthew Barnett30-Oct-23 5:47 
AnswerRe: Everything passed the same way Pin
Alexey Shtykov31-Oct-23 2:26
professionalAlexey Shtykov31-Oct-23 2:26 
Hello,
If all the things are references then why string changed inside and its value returned, but remains the same outside?
GeneralRe: Everything passed the same way Pin
Matthew Barnett31-Oct-23 7:45
Matthew Barnett31-Oct-23 7:45 
GeneralRe: Everything passed the same way Pin
Alexey Shtykov31-Oct-23 21:45
professionalAlexey Shtykov31-Oct-23 21:45 
GeneralRe: Everything passed the same way Pin
Matthew Barnett1-Nov-23 7:05
Matthew Barnett1-Nov-23 7:05 
QuestionFloating-point vs integer division Pin
Matthew Barnett26-Oct-23 7:33
Matthew Barnett26-Oct-23 7:33 
AnswerRe: Floating-point vs integer division Pin
Alexey Shtykov27-Oct-23 10:40
professionalAlexey Shtykov27-Oct-23 10:40 
GeneralMy vote of 5 Pin
Ștefan-Mihai MOGA25-Oct-23 6:39
professionalȘtefan-Mihai MOGA25-Oct-23 6:39 
GeneralRe: My vote of 5 Pin
Alexey Shtykov27-Oct-23 11:05
professionalAlexey Shtykov27-Oct-23 11:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.