I am currently trying to write an script which takes an user input and then prints it out through a class which is located in another file. But when running my script I have to give the programm the input twice which is then being printed out thrice because of an weird reason. I also searched up some other similar questions on stackoverflow but none of them helped me fixing my problem.
This is the code in the first file:
#this is main.py
global test_input
test_input = input('give me an input: ')
if 'i like cookies' in test_input:
from test import *
test_class.test()
This is the code in the second file:
#this is test.py
class test_class():
def test():
from main import test_input
print(test_input)
What the output looks like after running the script:
give me an input: i like cookies
give me an input: i like cookies #this second input is created because the function is being executed twice. In this example I would've typed in i like cookies twice
i like cookies
i like cookies
i like cookies
What the ouput should look like:
give me an input: i like cookies
i like cookies
I would be very very glad if someone could help me out with solving this problem and explaining to me what I've made wrong:)
Thank's for every suggestion and help in advance:)
It is punishing you for bad programming practices. ;) The issue is that, when you run a program, that module is not considered to be imported. So, when you get into test_class.test(), your from main statement actually causes your main program to be loaded AGAIN. It will do the input call again, and will call test_class.test() again. This time, main has already been imported, so it doesn't need to do it again, and thing go normally.
It is horrible practice for a submodule to try to import something from a main module. If your module function needs a value, then pass it as a parameter.
Related
So I'm pretty new to both coding and this website, so please bear with me if this is stupid:
I'm working on a personal project and would like to find a way to clear "print()" statements in python 3.6. For example:
print("The user would see this text.")
but if I continue
print("The user would see this text.")
print("They would also see this text.")
Is there a way to make it so a user would only see the second print statement?
I have seen "os.system('cls')" and "os.system('clear')" recommended, but I get these errors for each:
os.system('cls')
resulting in
sh: 1: cls: not found
and
os.system('clear')
resulting in
TERM environment variable not set.
Obviously I'm missing something, but if you know what it'd be much appreciated. If you know of another way to do what I'm thinking, that would also be awesome. Thank you for taking the time to read this, and thanks for any help.
Edit: I'm using Repl.it as my IDE. Could this be an issue with that site specifically?
Edit: Downloaded a new IDE to check, and the reply worked. If you are new and using Repl.it, be aware that some code does not function properly.
The method that I've used in the past to 'reprint' something on an existing line is to make use of the standard output directly, coupled with a carriage return to bring the printed statement's cursor back to the start of the line (\r = carriage return), instead of relying on the print function.
In pseudocode:
# Send what you want to print initially to standard output, with a carriage return appended to the front of it.
# Flush the contents of standard output.
# Send the second thing you want to print to standard output.
A working example in Python:
import sys
sys.stdout.write('\rThe user would see this text')
sys.stdout.flush()
sys.stdout.write('\rThe user would also see this text')
Edit
Figured I'd add an example where you can actually see the code working, since the working example above is going to execute so quickly that you'll never see the original line. The below code incorporates a sleep so that you can see it print the first line, wait, then reprint the line using the second string:
import sys
from time import sleep
sys.stdout.write('\rThe user would see this text')
sys.stdout.flush()
sleep(2)
sys.stdout.write('\rThe user would also see this text')
Heyo, I've run upon a problem.
So I have three files:
Main Program
Functions
Data
And I want the Main Program to call a function from the Functions module, which changes a variable in Data. Then I need to use the new variable elsewhere in the Main Program.
This is what I want, shown as a simplified demonstration program:
The Data file:
#data.py
#just an short depiction of my actual file
text = ""
The Functions file:
#functions.py
from data import *
def printHi():
global text
text = "hi"
print(text)
The Main Program:
#mainProgram.py
from functions import *
from data import *
printHi()
print(text)
What I expected would happen would be that when I run the Main Program:
The Functions file and Data file is imported.
Then it calls the "printHi" method from the Functions file.
The variable "text" from the Data file is assigned "hi", and is printed.
The the Main Program prints the "text" variable.
And I supposed that the text variable would be "hi". However, to my disappointment, it prints blank. It does indeed print the initial text value.
I really have NO idea why this is so. Shouldn't the text variable have already been changed? Could you please explain what part about my program is wrong and how to correct it?
The short answer is simply not to do this. It's a Bad Idea for all the reasons that global variables are always bad ideas: because they lead to stack overflow questions that read like "If I do this thing I shouldn't do, it does something I didn't expect -- why did it do that?" Whose easiest answer is, as you've now read, "That's why you shouldn't do that thing."
The long answer is a bit beyond me without spending a whole lot more time on the matter, but the longer answer is simple enough. When you do those "star" imports (from modulename import *) you're rebinding the name of the variable. What functions.printHi thinks of as text is not data.text but actually functions.text. When it's changed in printHi, it changes functions.text which should still be okay, since mainProgram is also importing functions.
However remember that mainProgram ISN'T actually importing functions, it's from functions import *'ing. That means what mainProgram thinks of as text is neither data.text nor functions.text, but mainProgram.text. When functions.printHi changes functions.text, it doesn't touch mainProgram.text.
The short answer applies here because these sorts of pitfalls are non-obvious unless you can think deeply enough about your code to understand them. If you are able to think that deeply about your code, you should be able to write something that can sidestep such pitfalls entirely. For instance: "global mutable state" is generally a bad thing. Avoid it.
To just make this work, drop all your "star" imports. The following code works:
# functions.py
import data
def printHi():
# plus! You don't need the `global` anymore.
data.text = "hi"
print(data.text)
# mainProgram.py
import functions
import data
functions.printHi() # prints "hi" from inside functions.printHi
print(data.text) # also prints "hi"
Cool, we have a lot of people saying "don't do this!". Well, what should you do then? The good way to do this is to pass the text variable into the function and out of it. Like so:
The Data file:
#data.py
#just an short depiction of my actual file
text = ""
The Functions file:
#functions.py
from data import *
def printHi(atext):
atext = "hi"
print(atext)
return atext
The Main Program:
#mainProgram.py
from functions import *
from data import *
text = printHi(text)
print(text)
That solves your problem. You should probably also get rid of the * imports as the other answer suggests but that's a philosophical question.
Before I begin, I know there are many questions that sound a lot like this one, but my question is a little different... So here it is...
As the title may of suggested, I am trying to call a function defined in my main.py script in an imported module. However, this situation is a bit different than that of a circular import situation. I have been doing a lot with pygame recently, and decided that I was gonna make a module that contains classes for buttons, text, sounds, and so on. But I want this file to be generic so it can be used with any game or application I make. Buttons usually have draw functions and stuff like that, so I can easily pass those variables into the functions without problem. The problem comes when I get to the part where I want to check if the button is clicked, and if it is do something. I want to have it set up so that I can pass in a string argument for a command, and use the eval() command on it (python 2.7). However, it throws the error of the function not being defined. I know why this is, but I want to see if there is anything I can do to get around this issue to keep the module as "generic" as possible. Below is a basic set of code to help explain what I want to do.
module1.py
class Button(object):
def __init__(self,x=0,y=0,image=None,command=""):
self.x = x
self.y = y
self.image = image
self.command = command
"""
Image this part filled with draw commands and stuff...
These functions work perfectly fine
"""
#Now here is the issue - local is mouse position
def checkClick(self, local):
#If statments here to determine if mouse over button and
#if mouse is clicked... The part below fails
eval(self.command)
main.py
import module1
import pygame
def quitgame():
pygame.quit()
quit()
local = pygame.mouse.get_pos()
b = module1.Button(command="quitgame")
#At this point lets assume that the mouse is overtop the button and the
#following function in the button will run
b.checkClick(local)
The error, as I said before states that the function I try to call is not defined. I have found a workaround for this, so I don't want answers that tell me how I can change this so it does not take a command as input. I would like however, to make it so I can input a command as an argument. Maybe I am not inputing a command the way I should, but I would like to do it like this, especially because the tkinter module allows you to enter a command as input/a variable. Maybe there is not a way to do this like I wish, but I really want to keep this code as reusable as possible with no changing required between games, and I would rather not have to put this code into my games/applications every time I make them (like I said before the code example I gave was just an example, my actual button code is much larger than what I did above). Like I said before as well, I know that there are many questions that are just like this one, but they have not helped me at all with this issue. The others suggested using scripts that are imported as well which contain addition variables and such, but I would rather not do this. Also, I have a workaround that completely gets rid of the issue, but it is not nearly as neat or easy as this would be.
As always, any help would be appreciated and thanks ahead of time for your answers in case I don't get back to you right away.
I want to have it set up so that I can pass in a string argument for a command, and use the eval() command on it (python 2.7).
No, no, no. Pass it a function:
# In main.py
b = module1.Button(command=quitgame)
# In module1.py
def checkClick(self, local):
...
self.command()
eval is almost never the right tool for any job.
If you don't want to define a function just to pass it as a command parameter, you can use a lambda for short (single-expression) functions:
b = module1.Button(command=lambda: do_whatever(some, arguments))
Files:
File 1: metrobot.py
File 2: irc.py
File 3: cmd.py
MetroBot.py starts irc.py, irc.py makes a while loop which then uses cmd.py.
I try reloading the cmd module from irc.py. After i've reloaded it, the changes in cmd.py still won't take effect.
Reload code snippet:
if ":!reload" in self.buf:
reload(sys.modules['cmd'])
I've also tried
reload(cmd)
None of the two works.
Anyone know what cause the reload to not work, or another simple way? This script is meant to be running at all times.
I created the following three mini-scripts to test this and it works:
bot.py:
import irc
def start():
irc.run()
irc.py:
import cmd, time
def run():
while 1:
print cmd.dothis()
reload(cmd)
time.sleep(1)
cmd.py:
def dothis():
return 1
Now if you run bot.start() it will print "1" once a second and if I then edit cmd.py at some point to say return 2 it prints "2".. Obviously I'm imagining this is a whole way simpler than whatever code you're having, but you'll need to post some samples to help us answer you better. Or try breaking your code down and testing the reload with a stripped down version of your code.
This is quite likely something simple that I have an issue with, but I do not have another machine to figure out if it's my laptop's python version right now.
When I run my program, I recieve the following error: "Type Error: function open() requires no arguments (2 given)"
The code snippet in question:
import tkinter as tk
from tkinter import filedialog as fdg
def update_queue():
conf_file = open("config.txt", "a")
fd = fdg.LoadFileDialog(master)
file = fd.go(pattern="*.jpg")
conf_file.write(file)
conf_file.close()
I'm not yet too good with Python, and would appreciate any pointers ("Your code looks twistier than last night's burnt spaghetti" counts as well) as to why the open() function fails.
Also of note, if I call open outside of a defined function, it opens the file, and can complete all actions done on it, but if I close the file, I cannot re open the file from within a function. I attempted to use the os file functions, but recieved the error "LoadFileDialog does not work with buffer-defined file functions." Understandable.
If I use conf_file.flush(), assuming I opened it outside of a function, will it flush whatever I write/append, so that I can read from the file again later?
EDIT: What I mean, is, will this work all the time, or would this be considered a hack?
is that the whole code? make sure you did not import another open function somewhere. or redefined it.
Assuming that open() was declared later on and you just didn't include it in the code, you probably declared it as
def open():
#code here
If this is the case, you just didn't add in the arguments when declaring the function and it should be:
def open(x, y):
#code here
where x and y could be anything you like.
Please come back and post the rest of your code (i highly doubt this is all of it) to get better answers. What is truly going on is at most a speculation on out part.