Python while loop not breaking - python

I'm a new programmer and I'm trying to make a rudimentary password generator. But I keep getting this problem where my while loop never breaks.
l1 = 'q w e r t y u i o p a s d f g h j k l z x c v b n m 1 2 3 4 5 6 7 8 9 0'
l2 = l1.split()
def genpass(n):
x = 0 if x == 0:
password = ''
if n < 100:
while n > x:
password = password + random.choice(l2)
x + 1
print(password)
else:
print 'Sorry, too long'
Can someone tell me what I'm doign wrong? Thanks.

You never change n or x here:
while n > x:
password = password + random.choice(l2)
x + 1
So if the condition was True initially it will always stay True and loop infinitely. Need to do x = x + 1
Incidentally this is the exact sort of bug that Pylint would catch for you.

Please consider the following:
1) Obvious condition
x = 0
if x == 0:
password = ''
You define x = 0, and then checks if x equals 0. It is invariably True.
Hence, you can change it this way:
x = 0
password = ''
2) While loop never ends
Before you had:
while n > x:
[some code]
x + 1 # here was your mistake
Consider these two ways you can add 1 to the variable x:
x = x + 1
or
x += 1
Both mean the same thing.
For further enlightment:
https://docs.python.org/3/reference/simple_stmts.html#augmented-assignment-statements

Can this help? :p
import random
l1 = 'q w e r t y u i o p a s d f g h j k l z x c v b n m 1 2 3 4 5 6 7 8 9 0'
l2 = list(l1.split())
def genpass(n):
x = 0
password=[]
if n < 100:
while n > x:
password.append(random.choice(l2))
x+=1
return ''.join(password)
else:
return('Sorry, too long')
#example with 14 char
print(genpass(14))

import random
l1 = 'q w e r t y u i o p a s d f g h j k l z x c v b n m 1 2 3 4 5 6 7 8 9 0'
l2 = l1.split()
def genpass(n):
password = ''
x = 0
if n < 100:
while n > x:
password = password + random.choice(l2)
x = x + 1
print(password)
else:
print 'Sorry, too long'
genpass(10)

You made quite a few errors in your code. What is x+1? It will be x=x+1. Please go through the basics first. Why are you checking if x==0, right after assigning x=0? Don't you think the if will always be yes? Your code in a cleaned format. Hope this works.
import random
l1 = 'q w e r t y u i o p a s d f g h j k l z x c v b n m 1 2 3 4 5 6 7 8 9 0'
l2 = l1.split()
def genpass(n):
x = 0
password = ''
if n < 100:
while n > x:
password = password + random.choice(l2)
x=x + 1
print(password)
else:
print ('Sorry, too long')
print("Enter how long you want your password to be")
genpass(int(input()))

You can try this, I've upgraded a little to generate more complex password.
import random
lower = 'q w e r t y u i o p a s d f g h j k l z x c v b n m'
nums = '1 2 3 4 5 6 7 8 9 0'.split()
upper = lower.upper().split()
spcl = '; ! # # & $ '.split()
all = lower.split() + nums + upper + spcl
def genpass(n):
x = 0
if x == 0:
password = ''
if n < 100:
while n > x:
password = password + random.choice(all)
x=x + 1
print(password)
else:
print('Sorry, too long')
# generates a sample password
genpass(10)

Related

How to do Alphabetic Spiral in python?

-- THE QUESTION --
Input : 3
Output :
A B C
H I D
G F E
Input : 5
Output :
A B C D E
P Q R S F
O X Y T G
N W V U H
M L K J I
-- My progress: --
print("input :")
n = int(input())
alphabet= 65
for i in range(n):
print((n+i)*" ")
for j in range(i, i+n):
print(chr(alphabet), end=" ")
alphabet = alphabet + 1
print()
Input : 5
Output :
A B C D E
F G H I J
K L M N O
P Q R S T
U V W X Y
Input : 3
Output :
A B C
D E F
G H I
This is not so trivial as it may seem. Anyway, here's a very simplistic solution:
build an alphabet long enough (I repeated the ASCII uppercase letters as needed so we can build spirals of any size)
create a matrix in memory with each letter in the right position
print the matrix
The code:
from string import ascii_uppercase
def spiral(n):
alphabet = ascii_uppercase * (n**2//26+1) #repeat ABC..XYZ until needed
alphabet = alphabet[:n**2] #take only n**2 chars
ln = len(alphabet)
grid = []
for _ in range(n):
grid.append([' ']*n)
min_row = 0
min_col = 0
max_row = n
max_col = n
i = 0
while i < ln:
#left to right
row = min_row
for col in range(min_col, max_col):
if i == ln:
break
grid[row][col] = alphabet[i]
i += 1
min_row += 1
#top to bottom
col = max_col-1
for row in range(min_row, max_row):
if i == ln:
break
grid[row][col] = alphabet[i]
i += 1
max_col -= 1
#right to left
row = max_row-1
for col in range(max_col-1, min_col-1, -1):
if i == ln:
break
grid[row][col] = alphabet[i]
i += 1
max_row -= 1
#bottom to top
col = min_col
for row in range(max_row-1, min_row-1, -1):
if i == ln:
break
grid[row][col] = alphabet[i]
i += 1
min_col += 1
#print grid
for row in range(n):
for col in range(n):
print(grid[row][col], end=' ')
print()
>>> spiral(3)
A B C
H I D
G F E
>>> spiral(9)
A B C D E F G H I
F G H I J K L M J
E D E F G H I N K
D C T U V W J O L
C B S B C X K P M
B A R A Z Y L Q N
A Z Q P O N M R O
Z Y X W V U T S P
Y X W V U T S R Q

Print nxn grid clockwise and print the sum of the diagonal elements

Example if n = 5 it should print
21 22 23 24 25
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
Sum = 21+7+1+3+13+17+5+9+25
= 101
Here is my code
dim=5
result= n = 1
for in range(2,dim,2):
for i in range(4):
n+=k
result+=n
print(result)
Here is what I made
def spiral(n):
# Initialize the values
m = [[0]*n for _ in" "*n] # Define a list of list of n dim
d = n
v = n*n # values
y = 0 # cord of y
x = n # cord of x
while d > 0:
for _ in" "*d: # Equivalent to <=> for i in range(d)
x -= 1
m[y][x] = v
v-=1
d -= 1
for _ in" "*d:
y += 1
m[y][x] = v
v-=1
for _ in" "*d:
x += 1
m[y][x] = v
v-=1
d -= 1
for _ in" "*d:
y -= 1
m[y][x] = v
v-=1
return m # return the list of list
n = 5
matrix = spiral(n)
# Print lines of the matrix
print("Matrix:")
for e in matrix:
print(*e)
# Print the sum
print(f"Sum: {sum(matrix[i][i]for i in range(n)) + sum(matrix[i][n - i - 1]for i in range(n)) - 1}") # There is a - 1 at the end, because the value of the middle is 1
You can rewrite the while loop like this:
while d > 0:
for i in range(4):
for _ in" "*d:
if i%2:
y -= 2 * (i==3) - 1
else:
x -= 2 * (i==0) - 1
m[y][x] = v
v-=1
if i%2 == 0:
d -= 1
It's shorter but less easy to understand
You can compute The Sum this way
def Spiral(size: int):
if(size<=1):
return 1
else:
Sum = 4*(size)**2 - 6(size-1)
return (Sum+Spiral(size-2))
Spiral(5)

How to create a table using a list of lists

I'm trying to write a file where you have 2 rows, with the first row being numbers and the 2nd row being letters. As an example, I was trying to do this with the alphabet.
list1=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
list2=list1+list1
abcList = [[],[]]
for i in range(len(list2)):
i+=1
if i % 5 == 0:
if i>=10:
abcList[0].append(str(i) + ' ')
else:
abcList[0].append(str(i) + ' ')
elif i<=1:
abcList[0].append(str(i) + ' ')
else:
abcList[0].append(' ')
for i,v in enumerate(list2):
i+=1
if i > 10:
abcList[1].append(' '+v+' ')
else:
abcList[1].append(v+' ')
print(''.join(abcList[0]))
print(''.join(abcList[1]))
with open('file.txt','w') as file:
file.write(''.join(abcList[0]))
file.write('\n')
file.write(''.join(abcList[1]))
The problem with the above setup is its very "hacky" (I don't know if its the right word). It "works", but its really just modifying 2 lists to make sure they stack on top of one another properly. The problem is if your list becomes too long, then the text wraps around, and stacks on itself instead of the numbers. I'm looking for something a bit less "hacky" that would work for any size list (trying to do this without external libraries, so I don't want to use pandas or numpy).
Edit: The output would be:
1 5 10
A B C D E F G H I J...etc.
Edit 2:
Just thought I'd add, I've gotten this far with it so far, but I've only been able to make columns, not rows.
list1=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
list2=list1*2
abcList = [[],[]]
for i in range(len(list2)):
i+=1
if i % 5 == 0:
if i>=5:
abcList[0].append(str(i))
elif i<=1:
abcList[0].append(str(i))
else:
abcList[0].append('')
for i,letter in enumerate(list2):
abcList[1].append(letter)
for number, letters in zip(*abcList):
print(number.ljust(5), letters)
However, this no longer has the wrapping issues, and the numbers line up with the letters perfectly. The only thing now is to get them from columns to rows.
Output of above is:
1 A
B
C
D
5 E
F
G
H
I
10 J
I mean, you could do something like this:
file_contents = """...""" # The file contents. I not the best at file manipulation
def parser(document): # This function will return a nested list
temp = str(document).split('\n')
return [[line] for line in temp] # List comprehension
parsed = parser(file_contents)
# And then do what you want with that
Your expected output is a bit inconsistent, since in the first one, you have 1, 6, 11, 16... and in the second: 1, 5, 10, 15.... So I have a couple of possible solutions:
print(''.join([' ' if n%5 else str(n+1).ljust(2) for n in range(len(list2))]))
print(''.join([c.ljust(2) for c in list2]))
Output:
1 6 11 16 21 26 31 36 41 46 51
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
print(''.join([' ' if n%5 else str(n).ljust(2) for n in range(len(list2))]))
print(''.join([c.ljust(2) for c in list2]))
Output:
0 5 10 15 20 25 30 35 40 45 50
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
print(''.join(['1 ']+[' ' if n%5 else str(n).ljust(2) for n in range(len(list2))][1:]))
print(''.join([c.ljust(2) for c in list2]))
Output:
1 5 10 15 20 25 30 35 40 45 50
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
If you are wanting to keep variable width strings aligned, you could use string formatting with a width equal to the maximum of the widths of the individual items in that position. (This example will work with more than any number of lists, by the way.)
list1 = ["", "5", "", "10", "", "4"]
list2 = ["A", "B", "C", "D", "EE", "F"]
lists = [list1, list2]
widths = [max(map(len, t)) for t in zip(*lists)]
for lst in lists:
line = " ".join("{val:{width}s}".format(val=val, width=width)
for val, width in zip(lst, widths))
print(line)
gives:
5 10 4
A B C D EE F

Is there a way for a for loop to not go back to the code on top if the next if statement is true?

a = 0
b = 0
for x in range (100):
a = a + 1
if a == 10:
b = b + 1
print(a)
print(b)
The outcome
99
1
What I want
10
90
IIUC, this should do the trick:
a = 0
b = 0
for x in range (100):
if a < 10:
a = a + 1
else:
b = b + 1
But to simplify further, you can use python's assignment operator, a += 1 syntax, which increments the value of a by 1:
a = 0
b = 0
for x in range (100):
if a < 10:
a += 1
else:
b += 1
Add a conditional check.
a = 0
b = 0
for x in range (100):
if (a % 10 != 0 or a==0):
a = a + 1
else:
b = b + 1
print(a)
print(b)
Just for fun:
a, b = 0, 0
for x in range(100):
add = a % 10 != 0 or a == 0
a += add
b += not add
This uses the fact that a bool is an int although I don’t advise it as it’s not too readable

Class Bug - NoneType and Int - Python [duplicate]

This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 6 years ago.
I have a coursework to do. I need to pass all the 6 tests that are required. I've passed 5, but having problem with one regarding the classes in Python.
def doomsday(y):
"""
>>> doomsday(2012)
3
>>> doomsday(1899)
2
>>> doomsday(1923)
3
>>> doomsday(10000)
-1
>>> doomsday(1756)
-1
>>> type(doomsday(2010))
<class 'int'>
"""
try:
y
except ValueError:
return
if y in range (1800, 1899+1):
x = 5
w = y%100
a = w//12
b = w%12
c = b//4
d = (a + b + c)%7
t = x + d
if t>6:
t = t - 7
print (t)
else:
print (t)
elif y in range (1900, 1999+1):
x = 3
w = y%100
a = w//12
b = w%12
c = b//4
d = (a + b + c)%7
t = x + d
if t>6:
t = t - 7
print (t)
else:
print (t)
elif y in range (2000, 2099+1):
x = 2
w = y%100
a = w//12
b = w%12
c = b//4
d = (a + b + c)%7
t = x + d
if t>6:
t = t - 7
print (t)
else:
print (t)
elif y in range (2100, 2199+1):
x = 0
w = y%100
a = w//12
b = w%12
c = b//4
d = (a + b + c)%7
t = x + d
if t>6:
t = t - 7
print (t)
else:
print (t)
else:
x = -1
print (x)
I cannot pass this test:
type(doomsday(2010))
class 'int'
And the error is:
Failed example:
type(doomsday(2010))
Expected:
class 'int'
Got:
0
class 'NoneType'
Your bug is probably coming from the fact that you think print() returns some value. It does not.
Your function does not return anything, therefore an implicit return with a return value of None will take place. If you want your function to return an integer, you need to do it explicitly. i.e Replace your print()'s with returns
From the Python Documentation on functions:
[...] even functions without a return statement do return a value [...], This value is called None (it’s a built-in name). Writing the value None is normally suppressed by the interpreter if it would be the only value written. [...]
(emphasis mine)
def doomsday(y):
"""
>>> doomsday(2012)
3
>>> doomsday(1899)
2
>>> doomsday(1923)
3
>>> doomsday(10000)
-1
>>> doomsday(1756)
-1
>>> type(doomsday(2010))
<class 'int'>
"""
try:
y
except ValueError:
return
if y in range (1800, 1899+1):
x = 5
w = y%100
a = w//12
b = w%12
c = b//4
d = (a + b + c)%7
t = x + d
if t>6:
t = t - 7
return t
else:
return t
etc...
Just need to return values instead of printing them:
def doomsday(y):
"""
>>> doomsday(2012)
3
>>> doomsday(1899)
2
>>> doomsday(1923)
3
>>> doomsday(10000)
-1
>>> doomsday(1756)
-1
>>> type(doomsday(2010))
<class 'int'>
"""
try:
y
except ValueError:
return
if y in range (1800, 1899+1):
x = 5
w = y%100
a = w//12
b = w%12
c = b//4
d = (a + b + c)%7
t = x + d
if t>6:
t = t - 7
return t
else:
return t
elif y in range (1900, 1999+1):
x = 3
w = y%100
a = w//12
b = w%12
c = b//4
d = (a + b + c)%7
t = x + d
if t>6:
t = t - 7
return t
else:
return t
elif y in range (2000, 2099+1):
x = 2
w = y%100
a = w//12
b = w%12
c = b//4
d = (a + b + c)%7
t = x + d
if t>6:
t = t - 7
return t
else:
return t
elif y in range (2100, 2199+1):
x = 0
w = y%100
a = w//12
b = w%12
c = b//4
d = (a + b + c)%7
t = x + d
if t>6:
t = t - 7
return t
else:
return t
else:
x = -1
return x

Categories

Resources