Django + MySQL : Round Robin Update of Same Table Columns - python

My Model is sort of like
Spot
spot_1 = 1/0
spot_2 = 1/0
spot_3 = 1/0
spot_4 = 1/0
spot_5 = 1/0
spot_6 = 1/0
Sort of like Round Robin Database, assuming the spot_1 represents Current Month, spot_2 represents the previous month, and so on. So if current month is June, so
Jun = spot_1
May = spot_2
Apr = spot_3
Mar = spot_4
Feb = spot_5
Jan = spot_6
So at the End of the Month of June, and Begining of July, this would be represented as
July = spot_1
Jun = spot_2
May = spot_3
Apr = spot_4
Mar = spot_5
Feb = spot_6
So the Values should be carried forward as well. Currently I am looping through the complete QuerySet and making the values to Move Forward.
How can this be achieved with Single update() statement ?

Use the F expressions:
from django.db.models import F
Spot.objects.all().update(spot_2=F('spot_1'), spot_3=F('spot_2'), ...)

Related

How i can fix this strange bug in my unit tests?

I was trying to create some unit test for my tweeter editor and i had a problem when i run the code. My unit test is this so far:
%%file test_twitter.py
import unittest
class TestTwitterEditor(unittest.TestCase):
"""Populate catalog"""
def setUp(self):
self.tweet[1] = tweet('Business Tax Accountant openings','Thu Sep 13 01:30:23 +0000 2012')
self.tweet[2] = tweet('Watching #XFactor USA beat show ever !!!', 'Thu Sep 13 0:30:23 +0000 2012')
self.tweet[3] = tweet('Random3', 'Thu Sep 18 5:30:23 +0000 2012')
self.tweet[4] = tweet('Random4', 'Thu Sep 17 5:30:23 +0000 2012')
self.tweet[5] = tweet('Random5', 'Thu Sep 18 7:30:23 +0000 2012')
def tearDown(self):
pass
def test_delete_tweet(self):
self.assertNotEqual(self.delete_tweet(0,0,0,5),'Random5')
def print_current_tweet(self):
self.assertEqual(self.print_current_tweet(tweet[5] , 0, 5),print(f"The current tweet is the number {tweet[5]} : \"{tweet[5]}\" Made at {tweet[5]}") )
if __name__ == '__main__':
unittest.main()
My delete_tweet function is this:
def delete_tweet(temp , temps , del_tweets , TOTAL_TWEET):
"""This function receives as input two temp.variables,a variable callled del_tweets"""
"""which will delete the current Id,and the number of total tweets which will be used"""
"""to track properly the current Id which is going to be deleted."""
"""It returns the temp.variables,the deleted tweet and the num of total tweets. """
tweet_id = int(input("Enter the id of the tweet you want to delete: "))
if (tweet_id <= TOTAL_TWEET):
del_tweets.append(tweet_id)
elif (tweet_id <= TOTAL_TWEET + temp):
for i in range(tweet_id + 1 , temp , 1):
temps[i] = temps[i + 1]
return temp , temps , del_tweets , TOTAL_TWEET
And the "error" thaty i receive is this:
Ran 0 tests in 0.000s
OK
Where is the problem?
I don't understand why I receive this red message. If the assertNotEqual was wrong or non valid i should receive a message like:Error οr something similar.

How to write a python for loop to reformat 31 different google sheets with pandas

I have a google spreadsheet and it has 31 tabs(the 31 days). What I want to do is to use my code to reformat the data (which I have solved), but I can't figure out how to use a for loop to apply the code to all 31 tabs/days. Since each tab is one day of the month, I want the code to go to the first tab, apply the code, and then jump to the next tab and apply the same code. I want this process to go on until it finishes with all 31 tabs.
Below is the code that I have tried, but it doesn't seem to work. I also have tried selecting multiple sheets and trying to select the google sheets' tab as the day, but this doesn't seem to be possible.
Jan = gc.open_by_url('with held for privacy reasons')
Jan = Jan.worksheet('01')
#for worksheet in Jan.worksheet:
#while Jan.worksheet is not 31:
if Jan.worksheet != 31:
Jan = get_as_dataframe(Jan)
Jan = pd.DataFrame(Jan)
day_month = Jan.worksheet
new_header = Jan.iloc[0]
Jan = Jan[1:]
Jan.columns = new_header
col_list = ['Time', 'Roof(in)', 'East(in)', 'West(in)', 'North(in)', 'Roof(out)', 'East(out)', 'West(out)', 'North(out)']
Jan = Jan[col_list]
Jan = Jan.dropna(axis=0, how='all')
Jan = Jan[:-2]
Jan.columns = ['DateTime', 'Business_Location_In', 'East_Location_In', 'West_Location_In', 'North_Location_In',
'Business_Location_Out', 'East_Location_Out', 'West_Location_Out', 'North_Location_Out']
Jan['DateTime'] = Jan['DateTime'].str.slice(6)
Jan['DateTime'] = pd.to_datetime('2019-01- ' + worksheet+ Jan['DateTime'])
for filename in Jan:
Jan['Jan'+ day_month] = filenames
while Jan.worksheet() < 31:
Jan = Jan.worksheet(day_month + 1)
elif Jan.worksheet == 31:
Jan = get_as_dataframe(Jan)
Jan = pd.DataFrame(Jan)
day_month = Jan.worksheet
new_header = Jan.iloc[0]
Jan = Jan[1:]
Jan.columns = new_header
col_list = ['Time', 'Roof(in)', 'East(in)', 'West(in)', 'North(in)', 'Roof(out)', 'East(out)', 'West(out)', 'North(out)']
Jan = Jan[col_list]
Jan = Jan.dropna(axis=0, how='all')
Jan = Jan[:-2]
Jan.columns = ['DateTime', 'Business_Location_In', 'East_Location_In', 'West_Location_In', 'North_Location_In',
'Business_Location_Out', 'East_Location_Out', 'West_Location_Out', 'North_Location_Out']
Jan['DateTime'] = Jan['DateTime'].str.slice(6)
Jan['DateTime'] = pd.to_datetime('2019-01- ' + worksheet+ Jan['DateTime'])
for filename in Jan: #this sets the file name to Jan and the day of month
Jan['Jan'+ day_month] = filenames
print(filenames)
One error that I have received is : AttributeError: 'Worksheet' object has no attribute 'worksheet'. I don't know what this means. Overall, I just can't seem to figure out how to apply the codes to all tabs and then to give me a list of all tab names. Additionally, this code doesn't need to be the same code. If someone is able to get this to work, but it rewrites all of the code, I am all for that. The date column should end up as year-month-day hour(military)-minute-second.

where's the problem with return from a function in python?

I didn't understand why the function does not return in python, My function counts the number of days (Friday and Saturday) between two dates but it does not return.
Here's my code :
# -*- coding: utf-8 -*-
import datetime
import calendar
calendar.setfirstweekday(calendar.SUNDAY)
from odoo import models, fields, api
class HrMission(models.Model):
_name = "hr.employee.mission"
_description = "hr mission"
_inherit = "hr.employee.mission"
days_compensation =fields.Float(compute='get_compensation', compstring='Jours de récupération', help="Jours de récupération si la mission contient les jours de repos",
required=True, readonly=True,)
#api.multi
#api.depends('mission_start_date', 'mission_end_date')
def get_compensation(self):
for rec in self:
if rec.mission_start_date and rec.mission_end_date:
time1 = datetime.datetime.strptime(rec.mission_start_date, "%Y-%m-%d")
time2 = datetime.datetime.strptime(rec.mission_end_date, "%Y-%m-%d")
week = {}
leave_value = {}
# Compute Number Of Friday And Saturday
for i in range((time2 - time1).days):
day = calendar.day_name[(time1 + datetime.timedelta(days=i+1)).weekday()]
week[day] = week[day] + 1 if day in week else 1
fri = week.get('Friday') if 'Friday' in week else 0 # Result Number 1 Of friday If "Start Date", "End date" --> "02/04/2019", "07/04/2019"
sat = week.get('Saturday') if 'Saturday' in week else 0 # Same thing that Friday, Numbre 1 for Saturday
friandsat = fri + sat # Result 2
rec.days_compensation = friandsat
You need to put this explicitly in your get_compensation() function:
return friandsat
Otherwise your function does not know that it needs to return something.
Firstly your function has no return statement, so it will return None.
Secondly in Odoo context it's a function for computed fields. There is no need to return anything, because they have to compute values for some fields. Just set those fields as you already do for days_compensation.

file processing in python

I'm working on text file processing using Python.
I've got a text file (ctl_Files.txt) which has the following content/ or similar to this:
------------------------
Changeset: 143
User: Sarfaraz
Date: Tuesday, April 05, 2011 5:34:54 PM
Comment:
Initial add, all objects.
Items:
add $/Systems/DB/Expences/Loader
add $/Systems/DB/Expences/Loader/AAA.txt
add $/Systems/DB/Expences/Loader/BBB.txt
add $/Systems/DB/Expences/Loader/CCC.txt
Check-in Notes:
Code Reviewer:
Performance Reviewer:
Reviewer:
Security Reviewer:
------------------------
Changeset: 145
User: Sarfaraz
Date: Thursday, April 07, 2011 5:34:54 PM
Comment:
edited objects.
Items:
edit $/Systems/DB/Expences/Loader
edit $/Systems/DB/Expences/Loader/AAA.txt
edit $/Systems/DB/Expences/Loader/AAB.txt
Check-in Notes:
Code Reviewer:
Performance Reviewer:
Reviewer:
Security Reviewer:
------------------------
Changeset: 147
User: Sarfaraz
Date: Wednesday, April 06, 2011 5:34:54 PM
Comment:
Initial add, all objects.
Items:
delete, source rename $/Systems/DB/Expences/Loader/AAA.txt;X34892
rename $/Systems/DB/Expences/Loader/AAC.txt.
Check-in Notes:
Code Reviewer:
Performance Reviewer:
Reviewer:
Security Reviewer:
------------------------
To process this file I wrote the following code:
#Tags - used for spliting the information
tag1 = 'Changeset:'
tag2 = 'User:'
tag3 = 'Date:'
tag4 = 'Comment:'
tag5 = 'Items:'
tag6 = 'Check-in Notes:'
#opening and reading the input file
#In path to input file use '\' as escape character
with open ("C:\\Users\\md_sarfaraz\\Desktop\\ctl_Files.txt", "r") as myfile:
val=myfile.read().replace('\n', ' ')
#counting the occurence of any one of the above tag
#As count will be same for all the tags
occurence = val.count(tag1)
#initializing row variable
row=""
#passing the count - occurence to the loop
for count in range(1, occurence+1):
row += ( (val.split(tag1)[count].split(tag2)[0]).strip() + '|' \
+ (val.split(tag2)[count].split(tag3)[0]).strip() + '|' \
+ (val.split(tag3)[count].split(tag4)[0]).strip() + '|' \
+ (val.split(tag4)[count].split(tag5)[0]).strip() + '|' \
+ (val.split(tag5)[count].split(tag6)[0]).strip() + '\n')
#opening and writing the output file
#In path to output file use '\' as escape character
file = open("C:\\Users\\md_sarfaraz\\Desktop\\processed_ctl_Files.txt", "w+")
file.write(row)
file.close()
and got the following result/File (processed_ctl_Files.txt):
143|Sarfaraz|Tuesday, April 05, 2011 5:34:54 PM|Initial add, all objects.|add $/Systems/DB/Expences/Loader add $/Systems/DB/Expences/Loader/AAA.txt add $/Systems/DB/Expences/Loader/BBB.txt add $/Systems/DB/Expences/Loader/CCC.txt
145|Sarfaraz|Thursday, April 07, 2011 5:34:54 PM|edited objects.|edit $/Systems/DB/Expences/Loader edit $/Systems/DB/Expences/Loader/AAA.txt edit $/Systems/DB/Expences/Loader/AAB.txt
147|Sarfaraz|Wednesday, April 06, 2011 5:34:54 PM|Initial add, all objects.|delete, source rename $/Systems/DB/Rascal/Expences/AAA.txt;X34892 rename $/Systems/DB/Rascal/Expences/AAC.txt.
But, I want the result like this:
143|Sarfaraz|Tuesday, April 05, 2011 5:34:54 PM|Initial add, all objects.|add $/Systems/DB/Expences/Loader
add $/Systems/DB/Expences/Loader/AAA.txt
add $/Systems/DB/Expences/Loader/BBB.txt
add $/Systems/DB/Expences/Loader/CCC.txt
145|Sarfaraz|Thursday, April 07, 2011 5:34:54 PM|edited objects.|edit $/Systems/DB/Expences/Loader
edit $/Systems/DB/Expences/Loader/AAA.txt
edit $/Systems/DB/Expences/Loader/AAB.txt
147|Sarfaraz|Wednesday, April 06, 2011 5:34:54 PM|Initial add, all objects.|delete, source rename $/Systems/DB/Rascal/Expences/AAA.txt;X34892
rename $/Systems/DB/Rascal/Expences/AAC.txt.
or it would be great if we can get results like this :
143|Sarfaraz|Tuesday, April 05, 2011 5:34:54 PM|Initial add, all objects.|add $/Systems/DB/Expences/Loader
143|Sarfaraz|Tuesday, April 05, 2011 5:34:54 PM|Initial add, all objects.|add $/Systems/DB/Expences/Loader/AAA.txt
143|Sarfaraz|Tuesday, April 05, 2011 5:34:54 PM|Initial add, all objects.|add $/Systems/DB/Expences/Loader/BBB.txt
143|Sarfaraz|Tuesday, April 05, 2011 5:34:54 PM|Initial add, all objects.|add $/Systems/DB/Expences/Loader/CCC.txt
145|Sarfaraz|Thursday, April 07, 2011 5:34:54 PM|edited objects.|edit $/Systems/DB/Expences/Loader
145|Sarfaraz|Thursday, April 07, 2011 5:34:54 PM|edited objects.|edit $/Systems/DB/Expences/Loader/AAA.txt
145|Sarfaraz|Thursday, April 07, 2011 5:34:54 PM|edited objects.|edit $/Systems/DB/Expences/Loader/AAB.txt
147|Sarfaraz|Wednesday, April 06, 2011 5:34:54 PM|Initial add, all objects.|delete, source rename $/Systems/DB/Rascal/Expences/AAA.txt;X34892
147|Sarfaraz|Wednesday, April 06, 2011 5:34:54 PM|Initial add, all objects.|rename $/Systems/DB/Rascal/Expences/AAC.txt.
Let me know how I can do this. Also, I'm very new to Python so please ignore if I've written some lousy or redundant code. And help me to improve this.
This solution is not as short and probably not as effective as the answer utilizing regular expressions, but it should be quite easy to understand. The solution does make it easier to use the parsed data because each section data is stored into a dictionary.
ctl_file = "ctl_Files.txt" # path of source file
processed_ctl_file = "processed_ctl_Files.txt" # path of destination file
#Tags - used for spliting the information
changeset_tag = 'Changeset:'
user_tag = 'User:'
date_tag = 'Date:'
comment_tag = 'Comment:'
items_tag = 'Items:'
checkin_tag = 'Check-in Notes:'
section_separator = "------------------------"
changesets = []
#open and read the input file
with open(ctl_file, 'r') as read_file:
first_section = True
changeset_dict = {}
items = []
comment_stage = False
items_stage = False
checkin_dict = {}
# Read one line at a time
for line in read_file:
# Check which tag matches the current line and store the data to matching key in the dictionary
if changeset_tag in line:
changeset = line.split(":")[1].strip()
changeset_dict[changeset_tag] = changeset
elif user_tag in line:
user = line.split(":")[1].strip()
changeset_dict[user_tag] = user
elif date_tag in line:
date = line.split(":")[1].strip()
changeset_dict[date_tag] = date
elif comment_tag in line:
comment_stage = True
elif items_tag in line:
items_stage = True
elif checkin_tag in line:
pass # not implemented due to example file not containing any data
elif section_separator in line: # new section
if first_section:
first_section = False
continue
tmp = changeset_dict
changesets.append(tmp)
changeset_dict = {}
items = []
# Set stages to false just in case
items_stage = False
comment_stage = False
elif not line.strip(): # empty line
if items_stage:
changeset_dict[items_tag] = items
items_stage = False
comment_stage = False
else:
if comment_stage:
changeset_dict[comment_tag] = line.strip() # Only works for one line comment
elif items_stage:
items.append(line.strip())
#open and write to the output file
with open(processed_ctl_file, 'w') as write_file:
for changeset in changesets:
row = "{0}|{1}|{2}|{3}|".format(changeset[changeset_tag], changeset[user_tag], changeset[date_tag], changeset[comment_tag])
distance = len(row)
items = changeset[items_tag]
join_string = "\n" + distance * " "
items_part = str.join(join_string, items)
row += items_part + "\n"
write_file.write(row)
Also, try to use variable names which describes its content. Names like tag1, tag2, etc. does not say much about the variable content. This makes code difficult to read, especially when scripts gets longer. Readability might seem unimportant in most cases, but when re-visiting old code it takes much longer to understand what the code does with non describing variables.
I would start by extracting the values into variables. Then create a prefix from the first few tags. You can count the number of characters in the prefix and use that for the padding. When you get to items, append the first one to the prefix and any other item can be appended to padding created from the number of spaces that you need.
# keywords used in the tag "Items: "
keywords = ['add', 'delete', 'edit', 'source', 'rename']
#passing the count - occurence to the loop
for cs in val.split(tag1)[1:]:
changeset = cs.split(tag2)[0].strip()
user = cs.split(tag2)[1].split(tag3)[0].strip()
date = cs.split(tag3)[1].split(tag4)[0].strip()
comment = cs.split(tag4)[1].split(tag5)[0].strip()
items = cs.split(tag5)[1].split(tag6)[0].strip().split()
notes = cs.split(tag6)
prefix = '{0}|{1}|{2}|{3}'.format(changeset, user, date, comment)
space_count = len(prefix)
i = 0
while i < len(items):
# if we are printing the first item, add it to the other text
if i == 0:
pref = prefix
# otherwise create padding from spaces
else:
pref = ' '*space_count
# add all keywords
words = ''
for j in range(i, len(items)):
if items[j] in keywords:
words += ' ' + items[j]
else:
break
if i >= len(items): break
row += '{0}|{1} {2}\n'.format(pref, words, items[j])
i += j - i + 1 # increase by the number of keywords + the param
This seems to do what you want, but I am not sure if this is the best solution. Maybe it is better to process the file line by line and print the values straight to the stream?
You can use a regular expression to search for 'add', 'edit' etc.
import re
#Tags - used for spliting the information
tag1 = 'Changeset:'
tag2 = 'User:'
tag3 = 'Date:'
tag4 = 'Comment:'
tag5 = 'Items:'
tag6 = 'Check-in Notes:'
#opening and reading the input file
#In path to input file use '\' as escape character
with open ("wibble.txt", "r") as myfile:
val=myfile.read().replace('\n', ' ')
#counting the occurence of any one of the above tag
#As count will be same for all the tags
occurence = val.count(tag1)
#initializing row variable
row=""
prevlen = 0
#passing the count - occurence to the loop
for count in range(1, occurence+1):
row += ( (val.split(tag1)[count].split(tag2)[0]).strip() + '|' \
+ (val.split(tag2)[count].split(tag3)[0]).strip() + '|' \
+ (val.split(tag3)[count].split(tag4)[0]).strip() + '|' \
+ (val.split(tag4)[count].split(tag5)[0]).strip() + '|' )
distance = len(row) - prevlen
row += re.sub("\s\s+([edit]|[add]|[delete]|[rename])", r"\n"+r" "*distance+r"\1", (val.split(tag5)[count].split(tag6)[0])) + '\r'
prevlen = len(row)
#opening and writing the output file
#In path to output file use '\' as escape character
file = open("wobble.txt", "w+")
file.write(row)
file.close()

Sorting by Year_Month Django filter

I try to show information order by year, month in a view, How can I improve my code for getting it?
Hint: I'm working in a report which shows sales ordering by year and month, Help me
Thanks.
views.py
def ventas_mes_anio(request):
ventas = Ventas.objects.filter(Fecha_registro__range=["2011-01-01", "2013-12-31"])
if ventas.is_valid():
enero = Ventas.objects.filter(Fecha_registro__month=1)
febrero = Ventas.objects.filter(Fecha_registro__month=2)
marzo = Ventas.objects.filter(Fecha_registro__month=3)
abril = Ventas.objects.filter(Fecha_registro__month=4)
mayo = Ventas.objects.filter(Fecha_registro__month=5)
junio = Ventas.objects.filter(Fecha_registro__month=6)
julio = Ventas.objects.filter(Fecha_registro__month=7)
agosto = Ventas.objects.filter(Fecha_registro__month=8)
septiembre = Ventas.objects.filter(Fecha_registro__month=9)
octubre = Ventas.objects.filter(Fecha_registro__month=10)
noviembre = Ventas.objects.filter(Fecha_registro__month=11)
diciembre = Ventas.objects.filter(Fecha_registro__month=12)
return render_to_response('ventasxproductosxmes.html',{'datos':ventas,'enero':enero,'febrero':febrero,'marzo':marzo,'abril':abril,'mayo':mayo,'junio':junio,'julio':julio,'agosto':agosto,'septiembre':septiembre,'octubre':octubre,'noviembre':noviembre,'diciembre':diciembre,},context_instance=RequestContext(request))
You can use a dict of month names instead of individual month name variables. (Your locale must be set correctly for month_name to be in your language)
import calendar
months = dict(zip(calendar.month_name[1:], [Ventas.objects.filter(Fecha_registro__month=x) for x in xrange(1,13)]))
You can then simply return the dict as context. Or, if you don't wish to change anything in the template side.
ret = {'datos':ventas}
ret.update(months)
return render_to_response('ventasxproductosxmes.html',ret,context_instance=RequestContext(request))

Categories

Resources