how to get total number of earnings using Thinkscript? - thinkscript

I want to count the total number of earnings on the chart. if this is 1 year daily chart, I should get 4 earnings back. no error message,but label is not showing on the chart.
def earningCount = if IsNaN(earningCount) then 0 else if hasEarnings() then earningCount + 1 else earningCount;
AddLabel(yes, "There are total " + earningCount + " earnings");

What you have to do is start with the first day and iterate through each previous day asking hasEarnings(). Unfortunately, without any for/while loop functionality in thinkscript, this will be extremely tedious:
def earningCount;
#get latest date
def today = getYYYYMmDd();
#get first date in chart
def firstDay = first(today);
#get number of days to iterate through:
def numOfDays = CountTradingDays(firstDay,today);
#Ask for each day one at a time: if hasEarnings() then earningCount + 1 else Double.NaN;
#today
today
#day before
today[1]
#day before that... etc..
today[2]
#... until first day in chart
today[numOfDays]
Not the optimal solution you would have wanted. Alternatively, you could ask how many years in the chart and multiple by 4 as you know there are usually 4 earnings/yr...

def earningCount = if IsNaN(earningCount[1]) then 0 else if hasEarnings() then earningCount[1] + 1 else earningCount[1];
AddLabel(yes, "There are total " + earningCount + " earnings");

Related

Get 1,2,3,4,5 star average individually (1star% +2star% +3star% +4star% +5star%=100%)

Suppose i have rated a user with 1 star 3 times, 2star 1times, 4star 4 times, 5star 10times.now from here anyone can find out overall average rating but how can i get the percentage of 1star,2star ,3star,4star and 5star from total rating
#show it on a django way
rating = Rating.objects.filter(activity__creator=u)
one_star_count = rating.filter(star='1').count()
two_star_count = rating.filter(star='2').count()
three_star_count = rating.filter(star='3').count()
four_star_count = rating.filter(star='4').count()
five_star_count = rating.filter(star='5').count()
total_stars_count = one_star_count + two_star_count+ \
three_star_count + four_star_count+ five_star_count
Create in your User model methods, that count the precentage and then simply use it as needed:
class User(...):
...
def count_star_precentage(self, star):
return (Rating.objects.filter(activity__creator=self, star=star).count() / self.all_ratings().count()) * 100
def all_ratings(self):
return Rating.objects.filter(activity__creator=self)
With them you can get precentage with simple call:
user = User.objects.get(id=some_id)
user.count_star_precentage(3) # it will give the percent of total ratings with 3 star given by that user

average spending per day - django model

I have a model that looks something like that:
class Payment(TimeStampModel):
timestamp = models.DateTimeField(auto_now_add=True)
amount = models.FloatField()
creator = models.ForeignKey(to='Payer')
What is the correct way to calculate average spending per day?
I can aggregate by day, but then the days when a payer does not spend anything won't count, which is not correct
UPDATE:
So, let's say I have only two records in my db, one from March 1, and one from January 1. The average spending per day should be something
(Sum of all spendings) / (March 1 - January 1)
that is divided by 60
however this of course give me just an average spending per item, and number of days will give me 2:
for p in Payment.objects.all():
print(p.timestamp, p.amount)
p = Payment.objects.all().dates('timestamp','day').aggregate(Sum('amount'), Avg('amount'))
print(p
Output:
2019-03-05 17:33:06.490560+00:00 456.0
2019-01-05 17:33:06.476395+00:00 123.0
{'amount__sum': 579.0, 'amount__avg': 289.5}
You can aggregate min and max timestamp and the sum of amount:
from django.db.models import Min, Max, Sum
def average_spending_per_day():
aggregate = Payment.objects.aggregate(Min('timestamp'), Max('timestamp'), Sum('amount'))
min_datetime = aggregate.get('timestamp__min')
if min_datetime is not None:
min_date = min_datetime.date()
max_date = aggregate.get('timestamp__max').date()
total_amount = aggregate.get('amount__sum')
days = (max_date - min_date).days + 1
return total_amount / days
return 0
If there is a min_datetime then there is some data in the db table, and there is also max date and total amount, otherwise we return 0 or whatever you want.
It depends on your backend, but you want to divide the sum of amount by the difference in days between your max and min timestamp. In Postgres, you can simply subtract two dates to get the number of days between them. With MySQL there is a function called DateDiff that takes two dates and returns the number of days between them.
class Date(Func):
function = 'DATE'
class MySQLDateDiff(Func):
function = 'DATEDIFF'
def __init__(self, *expressions, **extra):
expressions = [Date(exp) for exp in expressions]
extra['output_field'] = extra.get('output_field', IntegerField())
super().__init__(*expressions, **extra)
class PgDateDiff(Func):
template = "%(expressions)s"
arg_joiner = ' - '
def __init__(self, *expressions, **extra):
expressions = [Date(exp) for exp in expressions]
extra['output_field'] = extra.get('output_field', IntegerField())
super().__init__(*expressions, **extra)
agg = {
avg_spend: ExpressionWrapper(
Sum('amount') / (PgDateDiff(Max('timestamp'), Min('timestamp')) + Value(1)),
output_field=DecimalField())
}
avg_spend = Payment.objects.aggregate(**agg)
That looks roughly right to me, of course, I haven't tested it. Of course, use MySQLDateDiff if that's your backend.

How to get the number of Days in a Specific Month between Two Dates in Python

I have two date fields campaign_start_date and campaign_end_date. I want to count the number of days in each month that comes in-between the campaign_start_date and campaign_end_date.
eg:
campaign_start_date = September 7 2017
campaign_end_date = November 6 2017
The solution should be :
Total No:of days = 61 days
No: of months = 3 months
Month 1 = 9/7/2017 to 9/30/2017
Month 2 = 10/1/2017 to 10/31/2017
Month 3 = 11/1/2017 to 11/6/2017
No:of days in Month 1 = 24 days
No:of days in Month 2 = 31 days
No:of days in Month 3 = 6 days
How can I achieve this using Python?
So far I have achieved:
#api.multi
def print_date(self):
start_date = datetime.strptime(self.start_date, "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(self.end_date, "%Y-%m-%d %H:%M:%S")
campaign_start_date = date(start_date.year,start_date.month,start_date.day)
campaign_end_date = date(end_date.year,end_date.month,end_date.day)
duration = (campaign_end_date-campaign_start_date).days
return True
Calculate the duration in days:
from datetime import date
campaign_start_date = date(2017, 9, 7)
campaign_end_date = date(2017, 10, 6)
duration = (campaign_end_date-campaign_start_date).days
print campaign_start_date, campaign_end_date, duration
Some hints for further calculations:
import calendar
campaign_end_month_start = campaign_end_date.replace(day=1)
days_in_month_campaign_end = (campaign_end_date - campaign_end_month_start).days + 1
range_startmonth = calendar.monthrange(campaign_start_date.year, campaign_start_date.month)
campaign_start_month_ends = campaign_start_date.replace(day=range_startmonth[1])
days_in_month_campaign_begins = (campaign_start_month_ends - campaign_start_date).days
This way you can calculate the number of days in each month of the campaign (keep in mind to check if campaign_end_date is in another month than campaign_start_date
For calculations you can also access the fields of a date, e.g.
campaign_start_date.day
campaign_start_date.month
campaign_start_date.year
To calculate the number of involved month in your campaign and to get a list of the month to calculate the duration per month you can use this (based on the answer of m.antkowicz in Python: get all months in range?). It's important to set the day to 1 (current = current.replace(day=1)) before and inside the loop, otherwise you skip a month when your startdate is 31st of a month and the next month is shorter than 31 days or if you have a longer period:
from datetime import date, datetime, timedelta
current = campaign_start_date
result = [current]
current = current.replace(day=1)
while current <= campaign_end_date:
current += timedelta(days=32)
current = current.replace(day=1)
result.append(datetime(current.year, current.month, 1))
print result, len(result)
which prints (when you use current.strftime('%Y-%m-%d'):
['2017-09-07', '2017-10-01', '2017-11-01'] 3
now you can loop over the result list and calculate the number of days per months:
durations= []
for curr in result:
curr_range = calendar.monthrange(curr.year, curr.month)
curr_duration = (curr_range[1] - curr.day)+1
if (curr.month < campaign_end_date.month):
durations.append(curr_duration)
else:
durations.append(campaign_end_date.day)
print durations
which gives you the desired "No:of days in Month x" as a list:
[24, 31, 6]
This is the robust solution which takes care of dates from different years.
def get_months_and_durations(start_date,end_date):
current = start_date
result = [current]
current = current.replace(day=1)
while current <= end_date:
current += timedelta(days=32)
current = current.replace(day=1)
result.append(datetime(current.year, current.month, 1).date())
durations= []
for curr in result[:-1]:
curr_range = calendar.monthrange(curr.year, curr.month)
curr_duration = (curr_range[1] - curr.day)+1
if ((curr.month == end_date.month) & (curr.year == end_date.year)):
durations.append(end_date.day)
else:
durations.append(curr_duration)
return result[:-1],durations

Python Salary Program Using Conditionals

I get an error # line 19, the Bonus function and I can't figure out why. I'll probably get an error for the other functions too. I've checked my spaces, my numbers vs. my strings, and my DOM. My first problem were about my globals and I fixed it from global comrate to `comrate = 0; . I've got debugging blindness. Thank you guys in advance!
def main():
#Welcome user and get sales number
print("Welcome to the Bonus Qualification Calculator! Please honestly answer the following questions:")
name = str(input("What is your name? "))
sales = float(input("What is your sales total? "))
jobtime = float(input("How many months have you been with the company? "))
vacationtime = float(input("How many vacation days have you taken? "))
#Define Global Vars
comrate = 0;
compedsalary = 0;
bonussalary = 0;
finalsalary = 0;
#Begin calculations
Bonus(sales, jobtime)
vacation(vacationtime)
print(str(name) + ", your salary based on the information you provided is " + str(format(finalsalary,'.2f'))
def Bonus(sales,jobtime):
#Calcultate commission
if sales < 10000:
comrate = 0
elif sales > 10000 and sales <= 1000000:
comrate = .02
elif sales >= 100001 and sales <= 500000:
comrate = .15
compedsalary = float(comrate * 2000)
if jobtime > 3:
bonussalary = float(compedsalary + 1000)
else:
print("You don't qualify for a bonus due to your limited time at the company.")
elif sales >= 500001 and sales <= 1000000:
comrate = .28
compedsalary = float(comrate * 2000)
if jobtime > 3:
bonussalary = float(compedsalary + 5000)
else:
print("You don't qualify for a bonus due to your limited time at the company.")
elif sales > 1000000:
comrate = .35
compedsalary = float(comrate * 2000)
if jobtime > 3:
bonussalary = float(compedsalary + 100000)
elif jobtime > 60:
bonussalary = float(compedsalary + 101000)
else:
print("You don't qualify for a bonus due to your limited time at the company.")
def vacation(finalsalary):
if vacation > 3:
finalsalary = float(bonussalary - 200)
else:
finalsalary = bonussalary
main()
You're using full quotes where you should be using apostrophes. You're using contractions in your print statements, which confuses Python. Just put "do not" instead of "don't" in your print statements.

inserting a while loops into a for loop

I want to apply this while loop into the for loop below.
I have tried putting the while loop before the if statements, in each if statement.
When i put it before the if statement( in the for loop ) it asks the user once and then returns the same input for the whole range (1,8).
I want this while loop to apply to each question, the seven items 2 to 8
how do i implement it. can anyone help please, Thanks
def valid_entry ():
price = 110
invalid_input = 1
while price< 0 or price> 100:
if invalid_input >=2:
print "This is an invalid entry"
print "Please enter a number between 0 and 100"
try:
price= int(raw_input("Please enter your price : "))
except ValueError:
price = -1
invalid_input +=1
End of the while loop
def prices ():
x = range (1,8)
item=2
price=0
for item in x:
item +=1
print "\n\t\titem",item
price = int(raw_input("Enter your price : "))
if price <10:
price=1
print "This is ok"
if price >9 and price <45:
price +=5
print "This is great"
if price >44 and price <70:
price +=15
print "This is really great"
if price >69:
price +=40
print "This is more than i expected"
print "\nYou now have spent a total of ",price
prices ()
Is the lack of responses a sign that its a stupid question or is it not possible to do?
does this make it any clearer ?
def prices ():
x = range (1,8)
item=2
price=0
for item in x:
item +=1
print "\n\t\titem",item
valid_entry ()#should it go here
price = int(raw_input("Enter your price : "))
valid_entry ()#should it go here
if price <10:
valid_entry ()#should it go here and so on for the following 3 if conditions
price=1
print "This is ok"
if price >9 and price <45:
price +=5
print "This is great"
if price >44 and price <70:
price +=15
print "This is really great"
if price >69:
price +=40
print "This is more than i expected"
print "\nYou now have spent a total of ",price
You could try something like this (apologies if this isn't what you were looking for). Happy to explain anything that doesn't make sense - overall idea is that it loops through a range of 8 items, asking for a valid price each time and continuing to ask if the entered value is either not a number or not in the specified range. As this may be for an assignment, I tried to keep it as closely aligned to the concepts you already demonstrated that you knew (the only exception here may be continue):
def valid_entry():
# Here we define a number of attempts (which is what I think
# you were doing with invalid_input). If the person enters 10
# invalid attempts, the return value is None. We then check to
# see if the value we get back from our function is None, and if
# not, proceed as expected.
num_attempts = 0
while num_attempts < 10:
# Here we do the input piece. Note that if we hit a ValueError,
# the 'continue' statement skips the rest of the code and goes
# back to the beginning of the while loop, which will prompt
# again for the price.
try:
price = int(raw_input("Enter your price : "))
except ValueError:
print 'Please enter a number.'
num_attempts += 1
continue
# Now check the price, and if it isn't in our range, increment
# our attempts and go back to the beginning of the loop.
if price < 0 or price > 100:
print "This is an invalid entry"
print "Please enter a number between 0 and 100"
num_attempts += 1
else:
# If we get here, we know that the price is both a number
# and within our target range. Therefore we can safely return
# this number.
return price
# If we get here, we have exhausted our number of attempts and we will
# therefore return 'None' (and alert the user this is happening).
print 'Too many invalid attempts. Moving to the next item.'
return None
def prices():
# Here we go from 1-8 (since the upper bound is not included when
# using range).
x = range(1,9)
# Here we use a variable (total) to store our running total, which will
# then be presented at the end.
total = 0
# Now we iterate through our range.
for item in x:
print "\n\t\titem",item
# Here is the important part - we call our valid_entry function and
# store the result in the 'price' variable. If the price is not
# None (which as we saw is the return value if the number of attempts
# is > 10), we proceed as usual.
price = valid_entry()
if price is not None:
if price <10:
# Note this should probably be += 1
total += 1
print "This is ok"
elif price >= 10 and price < 45:
total += 5
print "This is great"
elif price >= 45 and price < 70:
total += 15
print "This is really great"
# We know that price >= 70 here
else:
total += 40
print "This is more than i expected"
# Now print out the total amount spent
print "\nYou now have spent a total of ", total
prices()