Stray new line after user input - python

Whilst attempting CS50's PSET6, I was trying to create a double-half pyramid of a size specified by the user.
The pyramid is fine but there's a random new line after the user input and before the pyramid starts. How can I fix it? Any help is appreciated :D
The code is as follows
def main():
hashHeight = height()
create(hashHeight)
# get height
def height():
h = int(input("Height: "))
if h >= 1 and h <= 8:
return h
else:
height()
#print hash
def create(x):
for i in range(x + 1):
print(" " * (x - i) + "#" * i + " " + "#" * i)
main()

def main():
hashHeight = height()
create(hashHeight)
# get height
def height():
h = int(input("Height: "))
if h >= 1 and h <= 8:
return h
else:
height()
#print hash
def create(x):
for i in range(1, x + 1):
print(" " * (x - i) + "#" * i + " " + "#" * i)
main()

Related

How do I convert all my print outputs into a single string

This code prints out a hollow rectangle with a given width and height using stars(*), but instead of printing each segment at a time I need to modify it or create a code that will create a single string that when printed produces the same output as the code above.
def print_rectangle(width, height):
for p in range(1):
print("*" * width)
for i in range(height - 2):
for i in range((width + 1) - width):
print("*", end='')
for n in range(width - 2):
print(" ", end='')
for j in range((width + 1) - width):
print("*", end='')
print("")
print("*" * width)
You need to create a variable, that saves the substrings, than print out the whole string, like this:
def print_rectangle(width, height):
tmp_str = ""
for p in range(1):
tmp_str = "*"*width+'\n'
for i in range(height-2):
for i in range((width+1)-width):
tmp_str += "*"
for n in range(width-2):
tmp_str += " "
for j in range((width+1)-width):
tmp_str += "*"
tmp_str += '\n'
tmp_str += "*"*width+'\n'
print(tmp_str)
print_rectangle(4, 5) #or any other numbers
The question has already been answered of how to correct your own code to make the rectangle, so here is a totally different way to accomplish the same thing:
def rectangle(width: int, height: int) -> str:
top_bottom = "*" * width
middle = "\n*" + (" " * (width - 2)) + "*"
rect = top_bottom
for _ in range(height - 2):
rect += middle
if height > 1:
rect += "\n" + top_bottom
return rect
print(rectangle(10, 5))
Output:
**********
* *
* *
* *
**********
You could build the lines into a list then join them for a single print operation. Here's an example:
width = 5
height = 6
t = ['*' * width + '\n']
m = '*' + ' ' * (width-2) + '*\n'
t.extend(m * (height - 2))
print(''.join(t+[t[0]]), end='')
Output:
*****
* *
* *
* *
* *
*****

I have already translated the type into int but still suffered a type error (python language)

def get_positive_int():
while True:
n = int(input("Height: "))
if n > 0 and n < 9:
return n
def print(n):
for i in range(n):
print(" " * (n - i) + "#" * i + " " + "#" * i)
def main():
n = get_positive_int()
print(n)
if __name__ == "__main__":
main()
and here is my error message:
TypeError: 'str' object cannot be interpreted as an integer
Since int(input()) has already translate n into an int I an curious why would n recieve an string?
The issue is that you have defined a custom function named print() and you call print() again in the loop. So, in the next recursion call, you call the custom defined print() with str object in print(" " * (n - i) + "#" * i + " " + "#" * i) and range() then throws the error since it expects an integer but it got an str object.
Change the name of the print() method to something else:
def get_positive_int():
while True:
n = int(input("Height: ").strip())
if n > 0 and n < 9:
return n
def print_0(n):
for i in range(n):
print(" " * (n - i) + "#" * i + " " + "#" * i)
def main():
n = get_positive_int()
print_0(n)
if __name__ == "__main__":
main()

How do I make random.randint refresh while program is running?

I'm making a small program that shoots out math problems and requires an answer to pass. It works fine, but all the randint values I generate stay static for as long as the progran is running. I figured if I change:
Tehtävä = random.choice(Laskut)
Into a function it should refresh with the loop. Problem is I can't for the life of me figure out how to do that. Would it even work for what I'm trying? The randint values are determined in a seperate list. Heres the rest of the code:
Peli = 1
while Peli != 2:
pulma = 1
refresh = 1
Tehtävä = random.choice(Laskut)
while pulma == 1:
ratkaisu = float(input(Tehtävä.problem + "\n:"))
if ratkaisu == Tehtävä.answer:
pulma += 1
refresh += 1
print("oikein")
elif ratkaisu == "loppu":
pulma += 1
refresh += 1
Peli += 1
else:
print("väärin")
Here are the values I used:
import random
class Algebra:
def __init__(self, problem, answer):
self.problem = problem
self.answer = answer
#Muuttujat
#erotus ja summa
a = random.randint(1,99)
b = random.randint(1,99)
c = random.randint(1,99)
d = random.randint(1,99)
#jako ja kerto
e = random.randint(1,10)
f = e*random.randint(1,10)
g = random.randint(1,10)
#Kysymykset
Kysymys_M = [str(a) + "+" + str(b) + "-x=" + str(c),
str(a) + "-" + str(b) + "-x=" + str(a),
str(a) + "-" + str(b) + "-" + str(c) + "-x=" + str(d),
str(e) + "*x=" + str(f),
str(f) + ":x=" + str(e),
"x:" + str(e) + "=" + str(g)]
#Vastaukset
Vastaus_M = [a+b-c,
-b,
a-b-c-d,
f/e,
f/e,
e*g]
Laskut = [
Algebra(Kysymys_M[0], Vastaus_M[0]),
Algebra(Kysymys_M[1], Vastaus_M[1]),
Algebra(Kysymys_M[2], Vastaus_M[2]),
Algebra(Kysymys_M[3], Vastaus_M[3]),
Algebra(Kysymys_M[4], Vastaus_M[4]),
Algebra(Kysymys_M[5], Vastaus_M[5]),]
(If I have packed too much information please let me know.)

Continue executing code without interrupting output of looping function

I have a while loop counting in centiseconds and printing the current_step var, always on the same line.
I want to run, for example,
x = True
while x is True:
pass #printing timer to CLI here
print('this is more code running while the timer is still running')
input('Press enter to stop the timer')
x = False
#When x becomes False, I want the while loop to terminate
I know this must involve subprocess or something of the likes, but I don't know what direction to point myself in for learning to solve this issue.
Here is the function for reference:
def timer(stawt, stahp, step, time_step):
from time import sleep
stawt = int(stawt)
stahp = int(stahp)
if stahp < 1:
stahp = 1
elif stahp > 1000:
stahp = 1000
stahp = stahp * 100 + 1
titerator = iter(range(stawt, stahp, step))
while True:
try:
current_step = str(next(titerator))
if int(current_step) < 99:
final_time = '0' + current_step[:0] + '.' + current_step[0:] + 's'
print('\r' + final_time, end='')
elif int(current_step) < 999:
final_time = current_step[:1] + '.' + current_step[1:] + 's'
print('\r' + final_time, end='')
elif int(current_step) < 9999:
final_time = current_step[:2] + '.' + current_step[2:] + 's'
print('\r' + final_time, end='')
else:
final_time = current_step[:3] + '.' + current_step[3:] + 's'
print('\r' + final_time, end='')
sleep(time_step)
except:
print(); break
seconds = int((int(current_step) / 100) % 60)
minutes = int((int(current_step) / 100) // 60)
if minutes < 1:
return ''
else:
final_time_human = str(minutes) + 'm ' + str(round(seconds)) + 's'
print(final_time_human + '\n')
def MAIN():
count_to = float(input('Enter max number of seconds to count:\n'))
print()
timer(0, count_to, 1, 0.01)
MAIN()
You need to use threading.
import threading
x = True
def thread_function():
while x is True:
pass #printing timer to CLI here
threading.Thread(target=thread_function).start()
# Continue with the other steps you want to take
# ...
# This will terminate the timer loop
x = False
Python threading documentation: https://docs.python.org/3/library/threading.html
If you want to print the time always at the same line you need to control terminal cursor. For more information checkout: How can move terminal cursor in Python?
Thanks to #dorukerenaktas, I have got this working. This is their answer adapted into my scriptlet:
import threading
from os import system
timer_thread = None
def timer(stawt, stahp, step, time_step):
from time import sleep
global run_timer
stawt = int(stawt)
stahp = int(stahp)
if stahp < 1:
print('Sorry, I limit min count to 1 second!\n')
stahp = 1
elif stahp > 1000:
print('Sorry, I limit max count to 1000 seconds!\n')
stahp = 1000
else:
print()
stahp = stahp * 100 + 1
titerator = iter(range(stawt, stahp, step))
def print_time():
while run_timer is True:
try:
current_step = str(next(titerator))
if int(current_step) < 99:
final_time = '0' + current_step[:0] + '.' + current_step[0:] + 's'
print('\r' + final_time, end='')
elif int(current_step) < 999:
final_time = current_step[:1] + '.' + current_step[1:] + 's'
print('\r' + final_time, end='')
elif int(current_step) < 9999:
final_time = current_step[:2] + '.' + current_step[2:] + 's'
print('\r' + final_time, end='')
else:
final_time = current_step[:3] + '.' + current_step[3:] + 's'
print('\r' + final_time, end='')
sleep(time_step)
except:
break
seconds = int((int(current_step) / 100) % 60)
minutes = int((int(current_step) / 100) // 60)
if minutes < 1:
return ''
else:
final_time_human = str(minutes) + 'm ' + str(round(seconds)) + 's'
print('\n' + final_time_human)
print_time()
def _init_timer():
global run_timer; run_timer = True
global timer_thread
print('Enter max number of seconds to count: ', end='')
count_to = float(input())
timer_thread = threading.Thread(target=timer, args=(0, count_to, 1, 0.01))
timer_thread.start()
print('\rPress enter to stop the timer:')
usr_input = input(); run_timer = False
system('clear')
_init_timer()
timer_thread.join()
print('\nGoodbye!')

Python Help - with “local variable referenced before assignment”

I have had problems with the shell saying local variable referenced before assignment and don't feel any previous answers have helped. Can I have some specific advice to this code:
Error : TotalExcessCharge = ExcessOneCharge + ExcessTwoCharge + ExcessThreeCharge + ExcessFourCharge + ExcessFiveCharge + ExcessPlusLimitCharge
UnboundLocalError: local variable 'ExcessThreeCharge' referenced before assignment
def BillingSystem(CustomerName,CustomerType,TotalGBUsed):
StandardCustomer = 1500
StandardQuota = 25
PremiumCustomer = 2500
PremiumQuota = 50
if (CustomerType == "Standard") or (CustomerType == "standard"):
if (TotalGBUsed > StandardQuota):
ExcessGB = TotalGBUsed - StandardQuota
for a in range(0, ExcessGB):
if (a <= 10):
ExcessOne = 250
ExcessOneCharge = a * ExcessOne
for b in range(0, ExcessGB):
if (b > 10) and (b <= 20):
ExcessTwo = 500
ExcessTwoCharge = b * ExcessTwo
for c in range(0, ExcessGB):
if (c > 20) and (c <= 30):
ExcessThree = 750
ExcessThreeCharge = c * ExcessThree
for d in range(0, ExcessGB):
if (d > 30) and (d <= 40):
ExcessFour = 1000
ExcessFourCharge = d * ExcessFour
for e in range(0, ExcessGB):
if (e > 40) and (e <= 50):
ExcessFive = 1250
ExcessFiveCharge = e * ExcessFive
for explus in range(0, ExcessGB):
if (explus > 50):
ExcessPlusLimit = 1500
ExcessPlusLimitCharge = explus * ExcessPlusLimit
TotalExcessCharge = ExcessOneCharge + ExcessTwoCharge + ExcessThreeCharge + ExcessFourCharge + ExcessFiveCharge + ExcessPlusLimitCharge
TotalCharge = StandardCustomer + TotalExcessCharge
print ("Total Excess Charge : " + str(TotalExcessCharge))
print ("Total Charge for this month : " + str(TotalCharge))
else:
print ("Total Excess Charge : 0")
print ("Total Charge for this month : " + str(StandardCustomer))
CName = input("[!] Customer Name : ")
CType = input("[!] Customer Type : ")
TotGB = int(input("[!] Total GB Usage : "))
BillingSystem(CName,CType,TotGB)
Obviously, at this point:
TotalExcessCharge = ExcessOneCharge + ExcessTwoCharge + ExcessThreeCharge + ExcessFourCharge + ExcessFiveCharge + ExcessPlusLimitCharge
your ExcessThreeCharge variable have not yet been assigned to, and that's because you assign to it under conditional:
for c in range(0, ExcessGB):
if (c > 20) and (c <= 30):
ExcessThree = 750
ExcessThreeCharge = c * ExcessThree
which might never be satisfied if ExcessDB is <= 20.
I'll not advise you how to fix it because, frankly, I do not understand the underlying logic of this code - it seems completely nonsensical to me.
The problem here is when your code doesn't go into the if conditions, your variables never get initiated but you have referred them at the end...So the error clearly tells you that you are calling the variable that you have never created or assigned. Always ensure that you refer the assigned variables!
And also you can make your code more easier to read like
using Excess# values directly inside the if conditions without assigning it to a variable.
using upper function on the input string and compare the value in one go..
def BillingSystem(CustomerName,CustomerType,TotalGBUsed):
StandardCustomer = 1500
StandardQuota = 25
PremiumCustomer = 2500
PremiumQuota = 50
ExcessOneCharge=0
ExcessTwoCharge=0
ExcessThreeCharge=0
ExcessFourCharge=0
ExcessFiveCharge=0
ExcessPlusLimitCharge=0
if (CustomerType.upper() == "STANDARD"):
if (TotalGBUsed > StandardQuota):
ExcessGB = TotalGBUsed - StandardQuota
for a in range(0, ExcessGB):
if (a <= 10):
ExcessOneCharge = a * 250
elif (a > 10) and (a <= 20):
ExcessTwoCharge = (a - 10) * 500
elif (a > 20) and (a <= 30):
ExcessThreeCharge = (a - 20) * 750
elif (a > 30) and (a <= 40):
ExcessFourCharge = (a - 30) * 1000
elif (a > 40) and (a <= 50):
ExcessFiveCharge = (a - 40) * 1250
elif (a > 50):
ExcessPlusLimitCharge = (a - 50) * 1500
TotalExcessCharge = ExcessOneCharge +
ExcessTwoCharge +
ExcessThreeCharge +
ExcessFourCharge +
ExcessFiveCharge +
ExcessPlusLimitCharge
TotalCharge = StandardCustomer + TotalExcessCharge
print ("Total Excess Charge : ", TotalExcessCharge)
print ("Total Charge for this month : ", TotalCharge)
else:
print ("Total Excess Charge : 0")
print ("Total Charge for this month : ", StandardCustomer)
CName = input("[!] Customer Name : ")
CType = input("[!] Customer Type : ")
TotGB = int(input("[!] Total GB Usage : "))
BillingSystem(CName,CType,TotGB)
And also instead of creating ExcessOneCharge, ExcessTwoCharge variables etc... You can do something like :
TotalExcessCharge = 0 #don't forget to initiate the variable at the beginning of the function
#then inside the if conditions
TotalExcessCharge += a*Excess#
This is just an example of how to write a cleaner code...logics you can apply as per your requirements!
Note : I'm typing everything in mobile, so pls ignore typos...
Because your definition of each of the "Excess#Charge" variables are within if statements, they seem not to be running for some reason. To fix this, I recommend defining all of the variables as 0 at the start so that if there is no excess value, it will simply be defined as 0. For example, at this at the top of the class:
ExcessOneCharge = 0
ExcessTwoCharge = 0
ExcessThreeCharge = 0
ExcessFourCharge = 0
ExcessFiveCharge = 0
ExcessPlusLimitCharge = 0

Categories