Python Forum
How to compare two parameters in a function that has *args?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to compare two parameters in a function that has *args?
#1
Question 
Hello team,

I have the following function

import string
import random

def check_input(*args):
    length = args[0]
    while length <= 0:
        length = int(input("[!] Please insert a positive integer: "))
    number = args[1]
    while length < number:
        number = int(input("[!] Please insert a positive integer: "))


check_input(-1)
check_input(5)
I would like to compare the first argument, in the above example it would ask to input another value instead of -1, and the second argument, in the above example 5.

I am getting the following error:

Error:
IndexError: tuple index out of range
I see *args prints the following when I
print(args)

(-1,)
(5,)
Could you please help me with how can I access the second and the following tuples to come for that function?

Thanks in advance.
Reply
#2
Could you explain the problem that you are trying to solve? It is very difficult to understand it through this function that does nothing useful.
buran likes this post
Reply
#3
(Mar-26-2023, 05:11 PM)Gribouillis Wrote: Could you explain the problem that you are trying to solve? It is very difficult to understand it through this function that does nothing useful.

Sure, I am glad you asked, so I am finishing my password generator, the main file looks like that

import random
import string
from logo import logo

print(logo)

# Generate string with all letters, numbers and symbols

def generate_password(n_letters, n_numbers, n_symbols):
    letters = "".join(random.sample(string.ascii_letters, n_letters))
    numbers = "".join(random.sample(string.digits, n_numbers))
    symbols = "".join(random.sample(string.punctuation, n_symbols))
    password = letters + numbers + symbols
    return "".join(random.sample(password, len(password)))


# Variable type verification
while True:
    try:
        length = int(input("[-] Choose the length of the password (Only integer): "))
        while length <= 0:
            length = int(input("[!] Please insert a positive integer: "))
        letters = int(input("[-] How many letters: "))
        while letters >= length:
            letters = int(input(f"[!] Amount of letters cannot be bigger than the password lenght, please insert a number lesser than {length}: "))
        numbers = int(input("[-] How many numbers: "))
        while numbers + letters > length:
            numbers = int(input(f"[!] Amount of numbers plus letter cannot be bigger than the password lenght, please insert a number lesser than {length - letters}: "))
        symbols = int(input("[-] How many symbols: "))
        while numbers + letters + symbols > length:
            symbols = int(input(f"[!] Amount of symbols plus letters and numbers cannot be bigger than the password lenght, please insert a number lesser than {length - letters - numbers}: "))
    except ValueError:
        print("[!] Invalid input, please enter an integer number")
        continue
    else:
        break
        
# Creates password based on user's input
password = generate_password(letters, numbers, symbols)
print(f"[+] Your password: {password}")
I would like to add a function to replace the many while loops between lines 21 and 31.

To my mind a function with *args would solve it, all I need is to know how to access the four arguments in it, they being 'length', 'letters', 'numbers' and 'symbols'.
Reply
#4
You are checking at the wrong time. Tell the user what they can enter and force them to enter values that are correct.
def get_number(prompt, range=None):
    """Force user to input number.  If range provided, input must be in range."""
    while True:
        try:
            value = int(input(prompt))
            if not range or range[0] <= value <= range[1]:
                return value
            print("Invalid input.  Try again")
        except ValueError:
            print("Invalid input.  Try again")


MAX_LENGTH = 30
MIN_LENGTH = 8
remaining = MAX_LENGTH - 2  # at least 1 lettter, number and special character

special = get_number(f"How many special characters (1-{remaining}): ", (1, remaining))
remaining = remaining - special + 1

if remaining > 2:
    numbers = get_number(f"How many numbers (1-{remaining}): ", (1, remaining))
else:
    numbers = 1

remaining = remaining - numbers + 1
if remaining > 1:
    min_letters = max(1, MIN_LENGTH - (special + numbers))
    letters = get_number(f"How many letters ({min_letters}-{remaining}): ", (min_letters, remaining))
else:
    letters = 1

print(letters, numbers, special)
To answer your question, you could do something like this:
def check(*args):
    """Force all args to be at least 1"""
    return [max(1, arg) for arg in args]
Reply
#5
(Mar-26-2023, 07:20 PM)deanhystad Wrote: You are checking at the wrong time. Tell the user what they can enter and force them to enter values that are correct.
def get_number(prompt, range=None):
    """Force user to input number.  If range provided, input must be in range."""
    while True:
        try:
            value = int(input(prompt))
            if not range or range[0] <= value <= range[1]:
                return value
            print("Invalid input.  Try again")
        except ValueError:
            print("Invalid input.  Try again")


MAX_LENGTH = 30
MIN_LENGTH = 8
remaining = MAX_LENGTH - 2  # at least 1 lettter, number and special character

special = get_number(f"How many special characters (1-{remaining}): ", (1, remaining))
remaining = remaining - special + 1

if remaining > 2:
    numbers = get_number(f"How many numbers (1-{remaining}): ", (1, remaining))
else:
    numbers = 1

remaining = remaining - numbers + 1
if remaining > 1:
    min_letters = max(1, MIN_LENGTH - (special + numbers))
    letters = get_number(f"How many letters ({min_letters}-{remaining}): ", (min_letters, remaining))
else:
    letters = 1

print(letters, numbers, special)
To answer your question, you could do something like this:
def check(*args):
    """Force all args to be at least 1"""
    return [max(1, arg) for arg in args]

Thank you very much.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  function accepts infinite parameters and returns a graph with those values edencthompson 0 868 Jun-10-2022, 03:42 PM
Last Post: edencthompson
  *args implementation and clarification about tuple status amjass12 10 4,068 Jul-07-2021, 10:29 AM
Last Post: amjass12
  [SOLVED] Good way to handle input args? Winfried 2 2,084 May-18-2021, 07:33 PM
Last Post: Winfried
  How can I write a function with three parameters? MehmetAliKarabulut 1 2,436 Mar-04-2021, 10:47 PM
Last Post: Larz60+
  Two Questions, *args and //= beginner721 8 3,521 Feb-01-2021, 09:11 AM
Last Post: buran
  Parameters aren't seen inside function Sancho_Pansa 8 2,956 Oct-27-2020, 07:52 AM
Last Post: Sancho_Pansa
  RuntimeError: Optimal parameters not found: Number of calls to function has reached m bntayfur 0 6,157 Aug-05-2020, 04:41 PM
Last Post: bntayfur
  Function parameters and values as string infobound 1 1,770 Jul-24-2020, 04:28 AM
Last Post: scidam
  does yield support variable args? Skaperen 0 1,688 Mar-03-2020, 02:44 AM
Last Post: Skaperen
  is there a way: repeat key word args Skaperen 2 2,249 Feb-03-2020, 06:03 PM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020