Printing data from python program to terminal on mac - python

I'm trying to get my code to output the results of really any code to my terminal, but I can't seem to find out why it won't print. I'm just learning to code so I've been finding a lot of explanation on this site kind of confusing, so apologies if this has been asked before.
This is my python file python.py:
class point(object):
def __init__(self, x, y):
self.x = float(x);
self.y = float(y);
def __str__(self):
return("(" + self.x + "," + self.y + ")")
def main():
first = point(2,3)
if __name__ == '__main__':
main()
and in the terminal I'm just typing "python python.py"

Add a print statement in the main() function to print to terminal:
class point(object):
def __init__(self, x, y):
self.x = float(x);
self.y = float(y);
def __str__(self):
return("(" + self.x + "," + self.y + ")")
def main():
first = point(2,3)
print(first)
if __name__ == '__main__':
main()

As others have mentioned, you need to add a print() call in your main function in order to get output to the terminal. Additionally, a few other things to note: Python doesn't require semi-colons, so there's no need for them in your __init__() method and you can't implicitly convert floats to strings, so you have to be explicit in your __str__() method.
class point(object):
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
def __str__(self):
# explicitly cast floats to strings
return "(" + str(self.x) + "," + str(self.y) + ")"
def main():
first = point(2,3)
print(first)
if __name__ == '__main__':
main()
Also, as MrTrustworthy pointed out, you don't need to call Class.__str__() directly as print first calls the __str__() method associated with the class. If there's no such method and implicit conversion fails, then you will get the representation of the calling function and the address in memory.
If you remove __str__() from your example, you should get output like this: <__main__.point object at 0x7f184cec4b70> if you try to print the object.

Related

Problems Appear in Visual Studio Code

I am a beginner at coding and currently in a python class at my university. I'm having some issues pop up in the "Problems" tab in Visual Studio Code. It wants me to put a self argument in my function inside a class, however when I call the class in my other file the code works it just displays problems. I tried putting self into the classes code and then everything stops working. The code was copied during the lecture and is the same code as my professor's using the same coding platform however his code doesn't show problems. I am attaching 2 screen shoots since the code is from 2 different files. I'm guessing something in my settings is causing this to happen. I have a similar thing happen when I do something like.for i in something: it will tell me i isn't defined yet the code will work.
Screenshot 1
Screenshot 2
Inside a class, that has non static methods, there must be a self variable.
class Math_Functions:
def addition(self, x, y): # there must be a self
return x + y
#... so on
This seems to be a static method, but VC may require you to still provide a self reference. Because python (at this specific case) does not require the self reference by default, when imported your code works file, but standalone, VC may tell you that you need an extra self there. Also you have an extra comma in addition after your y parameter.
Just simply pass in self into each of the methods (math functions), although it may work without it, it's good practice to do this if you want to continue learning OOP.
class mathFunctions:
def add(self, x, y): #Avoids the problem in VS
return x + y
It is required to pass in self for it to work when creating an object using a class using init, for example:
class employee:
def __init__(self, firstName, lastName, age):
self.firstName = firstName
self.lastName = lastName
self.age = age
def fullName(self):
return self.firstName + ' ' + self.lastName
#creating an object within the class
John = employee('John', 'Smith', '26')
#Returns "John Smith"
print(John.fullName())
Hope this might help, good luck on your python class!
This is a response to both replies. Putting self into the code creates a different problem and the code won't run because it tells me I am "missing 1 required positional argument: 'y'"
Three solutions:
First One:
In settings.json file add this configuration:
"python.linting.pylintArgs": [
"--disable=all",
"--enable=F,E,unreachable,duplicate-key,unnecessary-semicolon,global-variable-not-assigned,unused-variable,binary-op-exception,bad-format-string,anomalous-backslash-in-string,bad-open-mode",
"--disable=no-self-argument"
],
The first and second settings are the default settings of pylint, the third one can suppress the warning.
Second One:
Change your code to these:
main:
from calc import Math_functions as mf
print("Welcom to Calculator!")
x = int(input('Number: '))
y = int(input('Number: '))
op = input('Operation: ')
f = mf(x, y)
if op == '+':
print(f.addition())
elif op == '-':
print(f.subtraction())
elif op == '*':
print(f.multiplication())
elif op == '/':
print(f.division())
calc:
class Math_functions:
def __init__(self, x, y):
self.x = x
self.y = y
def addition(self):
return self.x+self.y
def subtraction(self):
return self.x-self.y
def multiplication(self):
return self.x*self.y
def division(self):
return self.x/self.y
Third One:
Change your code to these:
main:
import calc as mf
print("Welcom to Calculator!")
x = int(input('Number: '))
y = int(input('Number: '))
op = input('Operation: ')
if op == '+':
print(mf.addition(x, y))
elif op == '-':
print(mf.subtraction(x, y))
elif op == '*':
print(mf.multiplication(x, y))
elif op == '/':
print(mf.division(x, y))
calc:
def addition(x, y):
return x+y
def subtraction(x, y):
return x-y
def multiplication(x, y):
return x*y
def division(x, y):
return x/y

Output error using OOP

I'm having trouble finding the error in my code. I'm working with the class ColHe which is a collection of objects of type Header, and the main goal is to read a file's header and obtain a list with it's elements.
This is my Header class:
class Header:
def __init__(self, col):
self._day = 'Day:'
self._date = col[1]
self._time = 'Time:'
self._hours = col[3]
self._company = 'Company:'
self._name = 'NSHF'
def __str__(self):
return str(self._day + self._date + ", " + self._time + self._hours
+ ", " + self._company + self._name)
Along with its methods of getters and setters. And this is my ColHe class:
from collections import UserList
from copy import deepcopy
import constants
from Header import Header
class ColHe(UserList):
def __init__(self, file_name):
super().__init__()
in_file=open(file_name)
for i in range(constants.HEADER):
self.append(Header((in_file.readline().strip())))
in_file.close()
def getData(self):
return deepcopy(self)
def __str__(self):
st = ""
for he in self:
st+=str(he)
return st
Where constants.Header equals 6.
I ran the program with:
a=ColHe("file.txt")
print(a.getData())
And got this as an output:
Day:a, Time::, Company:NSHFDay:6, Time:1, Company:NSHFDay:i, Time:e, Company:NSHFDay:4, Time:5, Company:NSHFDay:o, Time:p, Company:NSHFDay:S, Time:F, Company:NSHF
However, the output I'm looking for looks more like this:
["Day:", self._date, "Time:", self._time, "Company:", "NSHF"]
An example of the content of a file would be:
Day:
06:11:2017
Time:
14:55
Company:
NSHF
When you print something in python, you don't print the name you have it stored under, you print its value. IE:
print(self._date) # print whatever is stored in _date
print("self._date") # print the static string 'self._date'
There's no reasonable way to get to your desired output from your demonstrated input. You're misunderstanding core concepts about what values are, where they are stored, and what happens when you reference them.
Use str.format (or f-strings if your code is python 3.6+ only)
def __str__(self):
return 'Day:\n{self._day}\nTime:\n{self._time}\nCompany:\n{self._company}'.format(self=self)

Where to change a value so it applies to all methods in python?

I am struggling with a problem that didn't seem to be a big deal in the beginning. I am creating aa class and a sub Subclass and whenever I want to change a value in subclass it should automatically update all the other methods in the class and subclass whenever I do that. Let me give you an example. The value that's supposed to be changed is shift in the change.shift(shift) method.
class Message(object):
'''
code that doesn't matter for this question
'''
def build_shift_dict(self, shift):
'''
code that doesn't matter for this question
'''
return dict
def apply_shift(self, shift):
'''
code that doesn't matter for this question
'''
return newMessage
class PlaintextMessage(Message):
def __init__(self, text, shift):
'''
code that doesn't matter for this question
'''
Message.__init__(self, text)
self.shift = shift
self.encrypting_dict = self.build_shift_dict(self.get_shift())
self.message_text_encrypted = self.apply_shift(self.get_shift())
def get_shift(self):
'''
Used to safely access self.shift outside of the class
Returns: self.shift
'''
return self.shift
def get_encrypting_dict(self):
return self.encrypting_dict
def get_message_text_encrypted(self):
return self.message_text_encrypted
def change_shift(self, shift):
assert 0 <= shift < 26
self.shift = shift
As you can see I need shift to be changed as well within apply_shift(self, shift) and build_shift_dict(self, shift) because the init method in PlaintextMessage(Message) calls does methods. How do I do that? When I call the get_shift(self) method I get the shift value, if I then call the change_shift(self, shift) method and call get_shift(self) again it shows me the updated shift value. So I tried to update self.encrypting_dict = self.build_shift_dict(self.get_shift()) and self.message_text_encrypted = self.apply_shift(self.get_shift()) with the get-Method instead of shift but that doesn't change anything. What am I missing here? Thanks!
In change_shift() just call those other two methods.
def change_shift(self, shift):
assert 0 <= shift < 26
self.shift = shift
self.encrypting_dict = self.build_shift_dict(self.shift)
self.message_text_encrypted = self.apply_shift(self.shift)
You could define build_shift_dict and apply_shift without an argument, other than self, and just use self.shift in those methods - you would still have to call them but you wouldn't have to pass them anything, and you couldn't mess it up by passing those methods an erroneous value from your program.
You could make access to shift a property/attribute using the #property decorator - you won't have to call it and you rid yourself of getter's and setter's - you would need to rename shift to something like _shift or __shift everywhere else in the program.
like:
class Foo:
def __init__(self, shift):
self._shift = shift
#property
def shift(self):
return self._shift
f = Foo(2)
Then you access it with f.shift.

Python - AttributeError

So for a line class I'm doing, I keep getting an error that says
AttributeError: Line instance has no attribute 'point0'
I'm declaring the line like this:
def __init__(self, point0, point1):
self.x = point0
self.y = point1
def __str__(self):
return '%d %d' % (int(round(self.point0)), int(round(self.point1)))
And I get the x and y from my point class which should already be float values so I don't need to check for an error in my init method however I do check to see if point0 and point1 are floats in my rotate method:
def rotate(self, a):
if not isinstance(a, float) or not isinstance(self.point0, float) or not isinstance(self.point1, float):
raise Error("Parameter \"a\" illegal.")
self.point0 = math.cos(a) * self.point0 - math.sin(a) * self.point1
self.point1 = math.sin(a) * self.point0 + math.cos(a) * self.point1
So why does python keep saying that it has no attribute point0? I also tried changing my init method to look like this:
def __init__(self, point0, point1):
self.point0 = point0
self.point1 = point1
But when I do that the error says point0 has no attribute float. So why do I keep getting this error? Here's the code I'm using to test:
p0 = Point(0.0, 1.0)
p1 = Point(2.0, 3.0)
line = Line(p0,p1)
print line
I'm curious... how much do you know about scope in Python?
In your class, you have a member variable named x and another named y. Your init function accepts an argument called point0 and another called point1. It saves point0 in the x member variable, and point1 in y. Then, in your rotate function, you attempt to access a variable called point0. Do you see the problem?
An important thing to understand when programming (and this is true in most programming languages, if not all of them) is that the name of an argument doesn't affect the name of that data elsewhere. I can pass a variable called foo into a function that takes an argument called bar. In that function, I have to refer to the data as bar because that's the name of the variable. Later, after I've called that function, the name of the variable is still foo, because only the variable inside the function is called bar. Does that make sense?
your class accept point0 and point1 parameters when you call it. If you want to get values of these parameters you should use self.x(for point0) and self.y(for point1)
or another way;
class Line:
def __init__(self, point0, point1):
self.point0 = point0
self.point1 = point1
I suggest you to read;
Python __init__ and self what do they do?
https://www.ibiblio.org/swaroopch/byteofpython/read/class-init.html
https://docs.python.org/2/tutorial/classes.html
A few overall points before displaying your corrected code. (Note that not much actually changed):
Don't bother checking argument types. Python programmers are assumed to be responsible enough to read the documentation and pass values of the correct value.
Your Line class was duplicating code that you had already defined in the Point class. The attributes of a line are Point instances, so you can use the methods you defined to implement the Line methods.
There's no reason to round the point coordinates to integers when displaying them; show the actual floating-point values that define the point. Your Line.__str__ method can take advantage of the fact that you've defined Point.__str__.
And now, your much shorter and corrected code, with some interspersed comments.
import math
class Point:
def __init__(self, x, y):
'''x and y should be floats'''
self.x = x
self.y = y
def rotate(self, a):
'''Rotate the point around the origin by a radians'''
self.x = math.cos(a) * self.x - math.sin(a) * self.y
self.y = math.sin(a) * self.x + math.cos(a) * self.y
# If you *were* going to check if a is a float, you
# need to do it *before* you use it.
def scale(self, f):
'''Scale the point by f units''' # you get the idea
self.x = f * self.x
self.y = f * self.y
def translate(self, delta_x, delta_y):
self.x = self.x + delta_x
self.y = self.y + delta_y
def __str__(self):
# If you're storing floats, it's probably useful
# to output them.
return '(%f, %f)' % (self.x, self.y)
# Operations on a line all involve applying the same operations
# to each of its end points.
class Line:
def __init__(self, point0, point1):
self.point0 = point0
self.point1 = point1
def rotate(self, a):
self.point0.rotate(a)
self.point1.rotate(a)
def scale(self, factor):
self.point0.scale(factor)
self.point1.scale(factor)
# If for whatever reason you didn't want to use Point.scale
# here, the code would be...
# self.point0.x = f * self.point0.x
# self.point0.y = f * self.point0.y
# self.point1.x = f * self.point0.x
# self.point1.y = f * self.point0.y
def translate(self, delta_x, delta_y):
self.point0.translate(delta_x, delta_y)
self.point1.translate(delta_x, delta_y)
def __str__(self):
# You've already defined out to turn a Point into
# a string, so you can take advantage of that here.
return "%s -- %s" % (self.point0, self.point1)
I'm going to add another answer here, both because I lack the reputation to comment on the other answer and because I feel this answer is unrelated to my previous answer (which addressed a different problem than what you're seeing now).
So. That said, look at this line of code:
return '%d %d' % (int(round(self.point0)), int(round(self.point1)))
round is a function that takes a numeric argument. However, self.point0 and self.point1 are not numbers. They are points. If you want the numbers from them, you'll have to refer to those explicitly (i.e. self.point0.x).

Confusion With OOP in Python

I'm trying to learn OOP in Python but I'm confused about some parts.
class Song(object):
def __init__(self, lyrics):
self.lyrics = lyrics
def sing_me_a_song(self):
for line in self.lyrics:
print line
def print_x(self):
print x
happy_bday = Song(["Happy birthday to you,",
"I don't want to get sued",
"So I'll stop right there"])
bulls_on_parade = Song(["They'll rally around the family",
"With pockets full of shells"])
happy_bday.sing_me_a_song()
bulls_on_parade.sing_me_a_song()
x = Song(4)
x.print_x()
print_x() returns:
<__main__.Song object at 0x7f00459b4390>
instead of 4. So I try adding x to the parameters for __init__ and print_x, and changing print x to print self.x in the print_x function plus adding self.x = x to init, but it returns this:
TypeError: __init__() takes exactly 3 arguments (2 given)
I honestly don't know what's gone awry here. But any help would be hugely beneficial to me finally understand OOP.
This is less an OOP issue and more of a scoping issue. Lets examine a very cut down version.
class Song(object):
def __init__(self, lyrics):
self.lyrics = lyrics
def print_x(self):
print x
From here we instantiate x (in the local scope):
>>> x = Song(4)
Now, before we do anything, lets examine x:
>>> print x.lyrics
4
The reason is that when you called Song(4) the value 4 is determined to be lyrics by its position.
And when we call print_x:
>>> x.print_x()
<__main__.Song object at 0x7f00459b4390> # Or some other memory address
The reason is that the only x that Python is aware of is the local x we just made.
What happens when we start again and make y:
>>> y = Song(4)
>>> print y.print_x ()
NameError: global name 'x' is not defined
No x exists to print and it throws an exception.
I think you are trying like
def __init__(self, lyrics, x):
self.lyrics = lyrics
self.x = x
...
def print_x(self):
print self.x
By this way it will produce TypeError: init() takes exactly 3 arguments (2 given)
You can find the error from this.
When you creating Song instance like
happy_bday = Song(["Happy birthday to you,",
"I don't want to get sued",
"So I'll stop right there"])
You have to pass the value of x to the __init__().Thats why the error is showing.This can done by
happy_bday = Song(["Happy birthday to you,",
"I don't want to get sued",
"So I'll stop right there"],
'x-value')
OR
Set default value for x
def __init__(self, lyrics, x="default value"):
self.lyrics = lyrics
self.x = x

Categories