This question already has answers here:
Convert string "Jun 1 2005 1:33PM" into datetime
(26 answers)
Closed 7 years ago.
I have this code:
from datetime import *
surname = ""
first_name = ""
birth_date = ""
nickname = ""
class Person(object):
def __init__(self, surname, first_name, birth_date, nickname=None):
self.surname = surname
self.first_name = first_name
self.birth_date = datetime.strptime(birth_date, "%Y-%m-%d").date()
self.nickname = nickname
if self.nickname is None :
self.nickname = self.surname
def get_age(self):
today = date.today()
age = today.year - self.birth_date.year
if today.month < self.birth_date.month:
age -= 1
elif today.month == self.birth_date.month and today.day < self.birth_date.day:
age -= 1
return str(age)
def get_fullname(self):
return self.surname + " " + self.first_name
petroff = Person("Petrov", "Petro", "1952-01-02")
print petroff.surname
print petroff.first_name
print petroff.nickname
print petroff.birth_date
print petroff.get_fullname()
print petroff.get_age()
print petroff.birth_date give me string "1952-01-02"
How I can change my code, to get the value of petroff.birth_date => datetime.date(1952, 1, 2)
According to datetime documentation, __str__ (which is called by print to obtain a printable view of an object) converts content of a date() to the string "1952-01-02". You can still compare date() objects as you want.
Related
I am expected to ensure the code is written without unnecessary lines of code. Is there a way to refactor this and get the same output?
def format_name(first_name, last_name):
if len(first_name) > 0 and len(last_name) > 0:
return("Name: " + last_name + ", " + first_name)
elif len(first_name) > 0 or len(last_name) > 0:
return("Name: " + first_name + last_name)
else:
empty_string = ""
return empty_string
return string
print(format_name("Ernest", "Hemingway"))
# Should return the string "Name: Hemingway, Ernest"
print(format_name("", "Madonna"))
# Should return the string "Name: Madonna"
print(format_name("Voltaire", ""))
# Should return the string "Name: Voltaire"
print(format_name("", ""))
# Should return an empty string
Without getting "too golfie", this should do the trick:
def format_name(first_name, last_name):
name = f"{first_name}, {last_name}".strip(", ")
return f"Name: {name}" if name else ""
The refactored method tries to allocate the logic of the function in a single if condition.
def format_name(first_name, last_name):
result = ''
sep = ', ' if first_name and last_name else ' '
if first_name or last_name:
result = last_name + sep + first_name
result = 'Name: ' + result.strip()
return result
print(format_name("Ernest", "Hemingway")) # "Name: Hemingway, Ernest"
print(format_name("", "Madonna")) # "Name: Madonna"
print(format_name("Voltaire", "")) # "Name: Voltaire"
print(format_name("", "")) # `empty_string`
Use str.join and filter to build the name string:
def format_name(first_name, last_name):
full_name = ", ".join(filter(None, (last_name, first_name)))
if full_name:
full_name = "Name: " + full_name
return full_name
import datetime
tday = datetime.date.today()
username =input('input something:')
class person:
def __init__(self, first, last, ip, birtyear, birthmonth, birthday):
self.first = first
self.last = last
self.ip = ip
self.birthyear = birtyear
self.birthmonth = birthmonth
self.birthday = birthday
def fullname(self):
return '{} {}'.format(self.first, self.last)
def yearage(self):
return '{}'.format(tday.year - self.birthyear)
def monthage(self):
return '{}'.format(tday.month - self.birthmonth)
def dayage(self):
return '{}'.format(tday.day - self.birthday)
def birth(self):
b1 = self.birthmonth, self.birthday,
b2 = self.birthyear
return'{} {}'.format(b1, b2)
def ip1(self):
return'{}'.format(self.ip)
names = ['x1', 'x2']
x1 = person('x1', 'y1', 50000, 2002, 2, 22)
x2 = person('x2', 'y2', 60000, 2004, 4, 24)
flag = 0
for i in names:
if (i==username):
print ((username).fullname())
flag=1
break
if (flag == 0):
print("element not found")
You need to add your persons to a list so you can search through it. Just because you have a variable called x1 does not mean you can use (username).fullname() to refer to that variable. Python doesn't work that way.
names = [
person('x1', 'y1', 50000, 2002, 2, 22)
person('x2', 'y2', 60000, 2004, 4, 24)
]
flag = 0
for user in names:
if user.first == username:
print( user.first, user.fullname())
flag=1
break
if flag == 0:
print("element not found")
The username is just the string the user gave as an input.
It therefore doesn't have the function fullname() you implemented for the person class.
I don't know what you are aiming for, you can either print the hardcoded "x1 y2" in the end or just reply what the user typed in.
My problem is:
In my following test, everything is working today but not will work tomorrow, I'm a beginner and did try a lot of options, but I failed, I,m trying pass "now" as a parameter but with no success until now.
I have to stop the "datetime.now()" and put one fixed date to can test all variations.
I had god progress until here, but I'm stuck on this
Can you help me, please?
Thank you.
Flavio
import unittest
from datetime import datetime
def get_last_name_and_birthday(name, d):
x = name.split()
dob = d.split("-")
year, month, day = int(dob[2]), int(dob[1]), int(dob[0])
user_birthday = datetime(year, month, day)
return x[-1], user_birthday
def calc_days(user_birthday):
now = datetime.now()
if user_birthday < now:
birthday = datetime(now.year + 1, user_birthday.month, user_birthday.day)
return (birthday - now).days + 1
else:
birthday = datetime(now.year, user_birthday.month, user_birthday.day)
return (birthday - now).days + 1
def generate_output(last_name, cd):
if cd == 365:
return "Hello Mr " + last_name + " Happy Birthday"
elif cd < 365:
return "Hello Mr " + last_name + " your birthday is in " + str(cd) + " days"
else:
return "Hello Mr " + last_name + " your birthday is in " + str(cd - 365) + " days"
def process_name_and_birthday(name, dob):
last_name, user_birthday = get_last_name_and_birthday(name, dob)
cd = calc_days(user_birthday)
return generate_output(last_name, cd)
#name = input("type your full name: ")
#dob = input("type your date of birthday(dd-mm-yy): ")
#print(process_name_and_birthday(name, dob))
class BirthdayTest(unittest.TestCase):
def test_same_day_birthday(self):
self.assertEqual("Hello Mr Oliveira Happy Birthday", process_name_and_birthday("Flavio Oliveira", "11-06-1990"))
class DaysToBirthdayTest(unittest.TestCase):
def test_days_to_birthday(self):
self.assertEqual("Hello Mr Oliveira your birthday is in 9 days", process_name_and_birthday("Flavio Oliveira", "20-06-1978"))
class DaysToPassedBirthdayTest(unittest.TestCase):
def test_how_many_days_passed_birthday(self):
self.assertEqual("Hello Mr Oliveira your birthday is in 364 days", process_name_and_birthday("Flavio Oliveira", "10-06-1978"))
unittest.main()
Add the following three lines under your import of datetime:
from unittest.mock import Mock
datetime = Mock(wraps=datetime)
datetime.now.return_value = datetime(2020, 6, 11, 20)
There is more information about the mock module here: https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock
When I define the __init__ of ProductionWorker, I also need to set the attributes of EmployeeClass. I entered "Bob" and "001121" as a test and it works but I need to be able to change it in my main from the input of the user.
class ProductionWorker(EmployeeClass):
SHIFT = {1: "day shift", 2: "night shift"}
def __init__(self, shift=None, hourly_pay=None):
EmployeeClass.__init__(self, "Bob", "001121")
self.__shift = shift
self.set_shift = shift
self.__hourly_pay = hourly_pay
self.set_hourly_pay = hourly_pay
# setters
def set_shift(self, shift):
if shift in ProductionWorker.SHIFT:
self.__shift = shift
else:
self.__shift = None
def set_hourly_pay(self, hourly_pay):
self.__hourly_pay = hourly_pay
# getters
def get_shift(self):
return self.__shift
def get_hourly_pay(self):
return self.__hourly_pay
def __str__(self):
summary = EmployeeClass.__str__(self)
return summary + "They work on the " + ProductionWorker.SHIFT[self.__shift] + " and make " + "$" \
+ str(format(self.__hourly_pay, "0.2f")) + " an hour."
My main:
from Employee import EmployeeClass
from Employee import ProductionWorker
e_name = input("Enter the name of the employee: ")
e_number = input("Enter the ID number of the employee: ")
e_shift = int(input("Enter 1 if they work day shift or 2 if they work night shift: "))
e_hourly_pay = float(input("Enter how much they make hourly (numerical): "))
x = EmployeeClass(e_name, e_number)
z = ProductionWorker(e_shift, e_hourly_pay)
print(z)
This is the result I get:
Enter the name of the employee: Joe
Enter the ID number of the employee: 5555
Enter 1 if they work day shift or 2 if they work night shift: 2
Enter how much they make hourly (numerical): 30
The employee's name is Bob. Bob's ID number is: 001121. They work on the night shift and make $30.00 an hour.
You have to use arguments as any with any other parameters:
class ProductionWorker(EmployeeClass):
SHIFT = {1: "day shift", 2: "night shift"}
def __init__(self, name, number, shift=None, hourly_pay=None):
EmployeeClass.__init__(self, name, number)
self._shift = shift
self.hourly_pay = hourly_pay
#property
def shift(self):
return self._shift
#shift.setter
def shift(self, shift):
if shift in ProductionWorker.SHIFT:
self._shift = shift
else:
self._shift = None
def __str__(self):
summary = EmployeeClass.__str__(self)
return summary + "They work on the {} and make ${:.2f} an hour.".format(
ProductionWorker.SHIFT[self.shift], self.hourly_pay)
name = input("Enter the name of the employee: ")
number = input("Enter the ID number of the employee: ")
shift = int(input("Enter 1 if they work day shift or 2 if they work night shift: "))
hourly_pay = float(input("Enter how much they make hourly (numerical): "))
z = ProductionWorker(name, number, shift, hourly_pay)
print(z)
I would include the parameters of the EmployeeClass in the init method parameters of the ProductionWorker to pass along to the superclass.
For python 3 you can do super().__init___() rather than EmployeeClass.__init__().
Additionally you should consider using descriptors rather than implementing getters and setters as that is the pythonic way to do that.
class ProductionWorker(EmployeeClass):
def __init__(self, name, number, shift=None, hourly_pay=None):
super().__init__(name, number)
self.__shift = shift
self.__hourly_pay = hourly_pay
When I run the following script, I get ValueError: invalid literal for int() with base 10: '2-' when the date only contains 1 digit (ie 02-02-2011). However it works fine when the date has 2 digits (ie 11-11-2011). What is the reason for this, and how can I fix it?
from __future__ import division
from easygui import *
import ystockquote
import datetime
import math
def main():
stock = 'NFLX'
name = ystockquote.get_company_name(stock)
start_date = create_date(02,13,2009)
end_date = create_date(10,21,2014)
start_price = get_price_on_date(stock,start_date)
end_price = get_price_on_date(stock,end_date)
if not isinstance(start_price,str):
print "Please enter a different start date, the market was closed on the day you chose!"
quit()
else:
start_price = float(start_price)
if not isinstance(end_price,str):
print "Please enter a different end date, the market was closed on the day you chose!"
quit()
else:
end_price = float(end_price)
no_of_shares = math.floor(10000/float(start_price))
profit = (end_price-start_price)*no_of_shares
print "The profit resulting from investing $10,000 in " + name + " from " + start_date + " to " + end_date + " would have been " + "$" + str(profit) + " or a return of {:.2%}".format(profit/10000) + " ."
def get_price_on_date(stock,date):
a = ystockquote.get_historical_prices(stock,date,date)
for key, value in a.iteritems() :
for key, value in value.iteritems() :
if key == 'Close':
return value
def create_date(month,day,year):
date_string = str(year) + "-" + str(month) + "-" + str(day)
return date_string
if __name__ == '__main__':
main()
Your create_date() function is not returning two-digit day and month numbers in all cases.
Try formatting the values explicitly instead of using str():
date_string = "{0:04}-{1:02}-{2:02}".format(year, month, day)