7
\$\begingroup\$

Is there anything specifically bad here, or anything that I could improve? Wasted lines of code, things done in a more memory intensive way than it could be, etc.

from random import*
b = 10
a = randint(1,b)
point = 1
x = 1
while x < 2:
    print("Guess a number between 1 and ", b)
    svar = int (input())
    if svar == a:
            b+=5
            point= point+point
            a = randint (1,b)
            print("You have ", point, "points!")
    elif svar < a:
            print("Higher")
    else:
            print("Lower")
\$\endgroup\$
0

5 Answers 5

7
\$\begingroup\$

Style

  1. The general standard for Python is to indent by four spaces, or by one tab with a width of four spaces.
  2. You shouldn't be doing wildcard imports, (from a import *).
  3. Your naming can be greatly improved. For example, the variable b could be renamed to maximum_guess_limit.
  4. Use str.format to format strings instead of using commas between string literals. Here's an example:

    # str.format without positional or named parameters
    print("{} {}".format("Hello", "world"))
    
    # str.format with positional parameters
    print("{1} {0}".format("world", "Hello"))
    
    # str.format with named parameters
    print("{word1} {word2}".format(word1="Hello", word2="world"))
    

Design

The logic in this program is very confusing, and with the bad variable names, it's not any easier to understand. From looking at the code, it looks like a number-guessing game of sorts, but I don't fully understand it's logic. I'd recommend encapsulating this into a function, or even separate functions. For example, to choose a random number based on a maximum integer, I'd create a function that looks something like this:

def choose_random_value(maximum_guess_limit):
    return randint(1, maximum_guess_limit)

In the end, I ended up with a result like this:

from random import randint


class NumberGuessingGame:
    def __init__(self, maximum_guess_limit):
        self.maximum_guess_limit = maximum_guess_limit
        self.__points = 0

    def __choose_random_integer(self):
        """
        Choose a random integer between one and the
        current maximum limit.
        """
        return randint(1, self.maximum_guess_limit)

    def __obtain_user_input(self, prompt):
        """
        Obtain the user input and ensure that
        it is a valid integer.
        """
        try:
            return int(input(prompt))
        except ValueError:
            print("You must enter a valid integer.")
            return None

    def __check_user_input(self, user_input, random_integer):
        """
        Check if the user guessed correctly, otherwise,
        display "Higher." or "Lower."
        """
        if user_input is not None:
            if user_input == random_integer:
                self.maximum_guess_limit += 5
                self.__points += self.__points

            elif user_input < random_integer:
                print("Higher.")

            else:
                print("Lower.")

    def play_game(self):
        while True:
            user_input = self.__obtain_user_input("Enter an integer: ")
            integer_to_guess = self.__choose_random_integer()
            self.__check_user_input(user_input, integer_to_guess)


game = NumberGuessingGame(10)
game.play_game()

It doesn't have support for exiting, but I'm sure you can implement it.

\$\endgroup\$
6
  • \$\begingroup\$ I only have a few hours of python experience so your code is very confusing to me but i will look it over and try to improve thank you very much. \$\endgroup\$ Commented Jul 20, 2015 at 20:41
  • \$\begingroup\$ @alexandercantos What book/resource are you using to learn Python? \$\endgroup\$ Commented Jul 20, 2015 at 20:42
  • \$\begingroup\$ @alexandercantos Also, if you found the answer helpful, you can click the up arrow to upvote it, and if you feel that this was the best answer for you, you can click the check mark to accept it. Otherwise, you can accept a different answer. \$\endgroup\$ Commented Jul 20, 2015 at 20:44
  • \$\begingroup\$ I don't have a book i had a very very introductory course at university. It cowered While,if else and some other basic things but i finished it in a few hours. The other things i found while googling. If you can recommend a place to learn with the fact that I'm super new in mind i would appreciate that. \$\endgroup\$ Commented Jul 20, 2015 at 21:07
  • \$\begingroup\$ @alexandercantos learnpythonthehardway.org/book \$\endgroup\$ Commented Jul 20, 2015 at 21:09
6
\$\begingroup\$

For a beginner I would consider this code to be pretty good. The code structure is clean, and has nothing "superfluous" - all the code is necessary, and the use of standard library functions to do the work is great.

The only real criticism I have is in the variable names. a, b, and svar are crummy names.

With a simple variable rename, your code is significantly better:

from random import*
limit = 10
target = randint(1,limit)
point = 1
x = 1
while x < 2:
    print("Guess a number between 1 and ", limit)
    guess = int (input())
    if guess == target:
            limit+=5
            point=point+point
            target = randint (1,limit)
            print("You have ", point, "points!")
    elif guess < a:
            print("Higher")
    else:
            print("Lower")

Hmm, that makes a few things more obvious.... like:

  1. what's x for? That's just an infinite loop.... and your code makes the loops hard to see (yes, I use loops as a plural there, there are actually 2 loops you have merged in to one....)
  2. you have a bug with point, you have point = point + point, but that should be point += 1. Instead, you are doubling point each time.

I would restructure your loops as follows:

from random import*
limit = 5
point = 1
while True:
    limit += 5
    print "Guess a number between 1 and", limit
    target = randint(1,limit)

    while True:
        guess = int (input())
        if guess == target:
            point += 1
            print "You have", point, "points!"
            break
        elif guess < target:
            print "Higher"
        else:
            print "Lower"

There's still an issue with the points, which should start at 0, and you may want to revise the system.

Note that the outer loop is a true infinite loop (using while True:), but the inner loop is essentially a do-while loop. Looping until the right number is guessed.

note the change to the print statements, which makes the output more readable on my computer too.

\$\endgroup\$
3
  • \$\begingroup\$ The point doubling was intentional as i wanted the increased difficulty to be rewarded. Everything else i will take into account going forward. Thank you very much. \$\endgroup\$ Commented Jul 20, 2015 at 20:39
  • \$\begingroup\$ I just look it over again and thought it was stuck then realized the break takes it out of the loop i assume. This will be very helpful thank you very much. Also i experienced an error when i pressed a non number for the guess(In my code not yours so i don't know if that is solved somewhere) this caused the program to end with a bunch of red error text. Is there some way to prevent that? \$\endgroup\$ Commented Jul 20, 2015 at 20:56
  • \$\begingroup\$ Those print statements should have parentheses around them. \$\endgroup\$ Commented Jul 20, 2015 at 21:06
2
\$\begingroup\$

Never use from a import *.

Use this:

import random
random.randint(1,b)

Or this:

from random import randint
randint(1,b)

Also, point = point + point can be shortened to:

point += point
\$\endgroup\$
1
  • \$\begingroup\$ I was told to use the * in my instructions that is why. I assume * imports everything associated with the word while your method only imports the parts i actually use? Thank you very much for teaching me this as I'm sure it will be immensely helpful going forward. \$\endgroup\$ Commented Jul 20, 2015 at 20:43
2
\$\begingroup\$
from random import*

As others have already noted, "import random" is superior.

b = 10
a = randint(1,b)

It's important to make your names as readable as possible, single letter names are ok only in limited cases. In general, the wider the scope of the variable, the longer its name should be.

point = 1

Not sure if a typo, but it should be 'points'.

x = 1
while x < 2:

Here's how you make an infinite loop:

while True:

.

print("Guess a number between 1 and ", b)

As others said, ".format()" is better.

svar = int (input())

if svar == a:
        b+=5
        point= point+point
        a = randint (1,b)

You should read https://www.python.org/dev/peps/pep-0008, which is pretty much the standard on how to format Python code. Here's your code, but with improved formatting:

svar = int(input())

if svar == a:
        b += 5
        point = point + point
        a = randint(1, b)

Here's your code, modified with the above in mind:

import random

range_start = 1
range_end = 10
random_number = random.randint(range_start, range_end)
points = 1

while True:
    guess = int(input("Guess a number between {} and {}\n".format(range_start, range_end)))
    if guess == random_number:
            range_end += 5
            points *= 2
            random_number = random.randint(range_start, range_end)
            print("You have {} points!".format(points))
    elif guess < random_number:
            print("Higher")
    else:
            print("Lower")

Now, this is closer to what I'd write:

import random

RANGE_START = 1


def main():
    range_end = 10
    points = 1

    while True:
        random_number = get_random_number(range_end)
        keep_user_guessing(range_end, random_number)

        range_end += 5
        points *= 2

        print("You have {} points!".format(points))


def get_random_number(range_end):
    return random.randint(RANGE_START, range_end)


def keep_user_guessing(range_end, random_number):
    while True:
        guess = get_guess_from_user(range_end)

        if guess == random_number:
            return

        if guess < random_number:
            print("Higher")
        else:
            print("Lower")


def get_guess_from_user(range_end):
    while True:
        guess = input("Guess a number between {} and {}\n"
            .format(RANGE_START, range_end))
        try:
            return int(guess)
        except ValueError:
            print("You must type a number!")


# You can read up about this line online,
# it's not very important for a beginner though.
if __name__ == "__main__":
    main()
\$\endgroup\$
0
0
\$\begingroup\$

Looks good, however a tip would be to use:

point += point

For example, if you wanted to add your variable b to point, instead of doing:

point = point + b

You could do:

point += b
\$\endgroup\$
4
  • \$\begingroup\$ Python doesn't have a ++ operator. \$\endgroup\$ Commented Jul 20, 2015 at 19:23
  • \$\begingroup\$ My bad, but the other holds true \$\endgroup\$ Commented Jul 20, 2015 at 19:23
  • \$\begingroup\$ I didn't realize you could do the += with anything besides numbers thank you very much for teaching me this. \$\endgroup\$ Commented Jul 20, 2015 at 20:44
  • \$\begingroup\$ @alexandercantos No problem, atleast you learned somethign \$\endgroup\$ Commented Jul 20, 2015 at 20:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.