逻辑错误:即使条件没有相遇,程序也会写入

发布于 2025-01-31 07:37:34 字数 2291 浏览 2 评论 0原文

我正在尝试读写文件。在此示例中,我正在尝试读取文件user_admin.txt,并检查文件中要求注册的用户名是否存在。如果存在,它将通过(在此处显示一条消息),如果没有,则以给定格式注册用户(in str (self)),

"""
    ***user_admin.txt contains(separate lines)***
    111124;;;zerox;;;32@3432#4$$
    344377;;;zer;;;32@3432#4$$
    424554;;;zero;;;32@3432#4$$
    544334;;;zeronda;;;32@8986#5$$
    655334;;;zIT;;;32@0000#8$$
    113324;;;Bazer;;;32@0000#4$$
"""

#jupyter cell 1

import os
import re

class Admin:

    path = "./data/result/user_admin.txt" 

    def __init__(self, id=-1, username="", password=""): # constructor
        self.id = id
        self.username = username
        self.password = password

    def __str__(self):
        return f"{self.id};;;{self.username};;;{self.password}"
    
    def register_admin(self):
        path = "./data/result/user_admin.txt"  # Destination of the user_admin.txt file
        
        with open(path, "r", encoding="utf-8") as r:  # r means read
            r_contents = r.read()
            user_match = re.findall(r'\d+;;;\w+;;;.*\n?', r_contents)
            
            with open(path, "a+", encoding="utf-8") as f:  # f means append and read
                if os.stat(path).st_size == 0:
                    f.write(f"{self.id};;;{self.username};;;{self.password}\n")
                elif os.stat(path).st_size != 0:
                    for i in range(len(user_match)):
                        if self.username not in user_match[i]:
                            f.write(f"{self.id};;;{self.username};;;{self.password}\n")
                        else:
                            print("You are not welcome here") # I will use "pass" in actual code
        


#jupyter cell 2
admin_two = Admin(113324,'Bazer','32@0000#4$$')
admin_two.register_admin()

#Juppyter cell 3
 with open(path, "r", encoding="utf-8") as r:  # f means append and read
 r_contents = r.read()
 print(r_contents)
 

单元3的结果是:

11124;;;zerox;;;32@3432#4$$
344377;;;zer;;;32@3432#4$$ 
424554;;;zero;;;32@3432#4$$
544334;;;zeronda;;;32@8986#5$$ 
655334;;;zIT;;;32@0000#8$$
113324;;;Bazer;;;32@0000#4$$
113324;;;Bazer;;;32@0000#4$$
113324;;;Bazer;;;32@0000#4$$
113324;;;Bazer;;;32@0000#4$$
113324;;;Bazer;;;32@0000#4$$
113324;;;Bazer;;;32@0000#4$$

i不了解导致此问题的逻辑错误是什么。非常感谢您的帮助:)

I am trying to read and write to file. In this example, I am trying to read the file user_admin.txt and check if the user's username who is requesting for registration exists in the file or not. If exists, it will pass(in here, shows a message) and if it doesn't then register the user in the given format (in str(self))

"""
    ***user_admin.txt contains(separate lines)***
    111124;;;zerox;;;32@3432#4$
    344377;;;zer;;;32@3432#4$
    424554;;;zero;;;32@3432#4$
    544334;;;zeronda;;;32@8986#5$
    655334;;;zIT;;;32@0000#8$
    113324;;;Bazer;;;32@0000#4$
"""

#jupyter cell 1

import os
import re

class Admin:

    path = "./data/result/user_admin.txt" 

    def __init__(self, id=-1, username="", password=""): # constructor
        self.id = id
        self.username = username
        self.password = password

    def __str__(self):
        return f"{self.id};;;{self.username};;;{self.password}"
    
    def register_admin(self):
        path = "./data/result/user_admin.txt"  # Destination of the user_admin.txt file
        
        with open(path, "r", encoding="utf-8") as r:  # r means read
            r_contents = r.read()
            user_match = re.findall(r'\d+;;;\w+;;;.*\n?', r_contents)
            
            with open(path, "a+", encoding="utf-8") as f:  # f means append and read
                if os.stat(path).st_size == 0:
                    f.write(f"{self.id};;;{self.username};;;{self.password}\n")
                elif os.stat(path).st_size != 0:
                    for i in range(len(user_match)):
                        if self.username not in user_match[i]:
                            f.write(f"{self.id};;;{self.username};;;{self.password}\n")
                        else:
                            print("You are not welcome here") # I will use "pass" in actual code
        


#jupyter cell 2
admin_two = Admin(113324,'Bazer','32@0000#4$')
admin_two.register_admin()

#Juppyter cell 3
 with open(path, "r", encoding="utf-8") as r:  # f means append and read
 r_contents = r.read()
 print(r_contents)
 

The result of Cell 3 is:

11124;;;zerox;;;32@3432#4$
344377;;;zer;;;32@3432#4$ 
424554;;;zero;;;32@3432#4$
544334;;;zeronda;;;32@8986#5$ 
655334;;;zIT;;;32@0000#8$
113324;;;Bazer;;;32@0000#4$
113324;;;Bazer;;;32@0000#4$
113324;;;Bazer;;;32@0000#4$
113324;;;Bazer;;;32@0000#4$
113324;;;Bazer;;;32@0000#4$
113324;;;Bazer;;;32@0000#4$

I don't understand what's the logical error causing this. I greatly appreciate your help :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暮色兮凉城 2025-02-07 07:37:34

Divide and Conquer

会将register_admin将拆分为3个函数:

  1. 解析文件以使用正则示意用户
  2. 查找所需的用户
  3. 注册用户

在此处求解 单个职责原理(SRP)

第一次搜索(是否找到),然后在分离的逻辑单元(函数或方法)中注册。

在循环中搜索

您可以使用for-loop在所有元素中搜索。
但是,请跟踪您的发现并在需要时尽早退出。

在此处求解 boolean flag 早期exit break break一起找到。

代码建议

# first decompose the methods in Cell 1 (split into smaller problem-solutions)

# (1) parse users
# class method, thus no self
def parse_users(path): 
    user_matches = []
    with open(path, "r", encoding="utf-8") as r:  # r means read
        r_contents = r.read()
        user_matches = re.findall(r'\d+;;;\w+;;;.*\n?', r_contents)
    return user_matches

# (2) find in users  (the search logic in the loop was the issue)
def find_in_users(self, user_matches):
    # search in all elements of user_matches
    found = False  # use a flag, which will turn True as soon as was found
    for i in range(len(user_matches)):
        if self.username in user_match[i]:  # remove `not` to find 
            found = True
            break  # as soon as found we must exit the loop
    # out of the loop: test if not in elements of user_matches at all
    return found

# (3) register at file
def register_at(self, path)
    user_matches = parse_users(path) 
    found = find_in_users(self, user_matches)
    if not found:  # may have two reasons: (a) no user in file or file size 0, (b) searched user not found   
        # append it to the file            
        with open(path, "a+", encoding="utf-8") as f:  # f means append and read
            if os.stat(path).st_size == 0:
                f.write(f"{self.id};;;{self.username};;;{self.password}\n")
            elif os.stat(path).st_size != 0:        
                f.write(f"{self.id};;;{self.username};;;{self.password}\n")
    else:
        print("You are not welcome here") # I will use "pass" in actual code


# then later in Cell 2
admin_two = Admin(113324,'Bazer','32@0000#4$')
admin_two.register_at(path)

# finally in Cell 3

进一步的问题并优化

重要的是:文件大小或发现?

如果文件为空,是否真的很重要(os.stat(path).st_size)?

注册重要的结果是:

  • 没有找到管理员,

因此我们可以简化这些行:

            if os.stat(path).st_size == 0:
                f.write(f"{self.id};;;{self.username};;;{self.password}\n")
            elif os.stat(path).st_size != 0:        
                f.write(f"{self.id};;;{self.username};;;{self.password}\n")

to:

            f.write(f"{self.id};;;{self.username};;;{self.password}\n")

在整个CSV线中找到单词?!

如果文件中的任何用户选择admin的名称bazer作为密码怎么办?

考虑以下行:

424554;;;zero;;;Bazer

尽管实际用户名是Zero,但它将发现用户被搜索为Bazer

您可以通过使用捕获组调整正则表达式来提取用户名。因此,user_matches将是一个用户名的列表,只有例如eg ['zer','Zero']

甚至更好地将真实的CSV-Parser模块用于Python。

Divide and Conquer

Would split the register_admin into 3 functions instead:

  1. parse file to get users using regex
  2. find desired user
  3. register user at file

Solving here is the separation of concerns or single responsibility principle (SRP):

First search (find or not), then register - in separated logical units (functions or methods).

Search in a loop

You can search in all elements with for-loop.
But keep track of your findings and exit early if needed.

Solving here is the boolean flag found together with early-exit break.

Code suggested

# first decompose the methods in Cell 1 (split into smaller problem-solutions)

# (1) parse users
# class method, thus no self
def parse_users(path): 
    user_matches = []
    with open(path, "r", encoding="utf-8") as r:  # r means read
        r_contents = r.read()
        user_matches = re.findall(r'\d+;;;\w+;;;.*\n?', r_contents)
    return user_matches

# (2) find in users  (the search logic in the loop was the issue)
def find_in_users(self, user_matches):
    # search in all elements of user_matches
    found = False  # use a flag, which will turn True as soon as was found
    for i in range(len(user_matches)):
        if self.username in user_match[i]:  # remove `not` to find 
            found = True
            break  # as soon as found we must exit the loop
    # out of the loop: test if not in elements of user_matches at all
    return found

# (3) register at file
def register_at(self, path)
    user_matches = parse_users(path) 
    found = find_in_users(self, user_matches)
    if not found:  # may have two reasons: (a) no user in file or file size 0, (b) searched user not found   
        # append it to the file            
        with open(path, "a+", encoding="utf-8") as f:  # f means append and read
            if os.stat(path).st_size == 0:
                f.write(f"{self.id};;;{self.username};;;{self.password}\n")
            elif os.stat(path).st_size != 0:        
                f.write(f"{self.id};;;{self.username};;;{self.password}\n")
    else:
        print("You are not welcome here") # I will use "pass" in actual code


# then later in Cell 2
admin_two = Admin(113324,'Bazer','32@0000#4$')
admin_two.register_at(path)

# finally in Cell 3

Further issues and optimization

What matters: file-size or found?

Is it really important if the file is empty or not (if os.stat(path).st_size) ?

Result that matters for registration is:

  • just no admin was found

So we could simplify those lines:

            if os.stat(path).st_size == 0:
                f.write(f"{self.id};;;{self.username};;;{self.password}\n")
            elif os.stat(path).st_size != 0:        
                f.write(f"{self.id};;;{self.username};;;{self.password}\n")

to:

            f.write(f"{self.id};;;{self.username};;;{self.password}\n")

Find word in entire CSV line ?!

What if any user in the file has chosen the admin's name Bazer as password?

Consider this line:

424554;;;zero;;;Bazer

It will find the user searched as Bazer although the actual username is zero.

You could just extract the user-names by adjusting the regex with capture-groups. So the user_matches would be a list of user-names only like e.g. ['zer', 'zero'].

Or even better use a real CSV-parser module for Python.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文