Python (Pywin32) Referencing Own Cell/Horizontal Movement - python

So please don't tell me to google or research or read anything, I've been doing that for the past couple of days and will get annoyed if I see someone say that again.
My problem: I am using pywin32 and python 2.7.8 to communicate with (an already existing) excel sheet. I use it to log my hours worked and money earned, etc. I have it functioning to the point that I can open the workbook, find the next empty cell under my existing entries and write the date in that cell. My problem lies in the fact that I need to navigate horizontally. I want the program to run automatically so I will not always know the number of the cell. For example, my current cell is 18,1. I need to move to 18,2 18,3 18,4 and 18,5. But next time I run the script I may need 19,2... etc.
How can I do this? Is there a way to return the current cell or something?
code:
import win32com.client as win32
import os, time
xl = win32.Dispatch('Excel.Application')
xl.visible = True
xl.Workbooks.Open(os.path.join('C:\\Users\\[REDACTED]\\Desktop', '[REDACTED].xls'))
xlSheet = xl.Sheets(1)
activecell = xlSheet.Cells(1,1)
def GetEmptyCell():
global activecell
activecell = xlSheet.Cells(1,1)
for c in range(1,99,1):
if activecell.Value == None:
print 'Empty cell'
activecell = xlSheet.Cells(c,1)
print '(' + str(c) + ',1)'
return activecell
elif activecell.Value != None:
c += 1
activecell = xlSheet.Cells(c,1)
print 'Full cell, next'
GetEmptyCell()
def WriteToEmpty():
global activecell
global HoursWorked
global GrossIncome
global NetIncome
HoursWorked = raw_input('Input amount of hours worked: ')
GrossIncome = float(HoursWorked) * 9.15
NetIncome = float(GrossIncome) * 0.86233
print 'Money Made: ' + str(GrossIncome) + ' Take Home: ' + str(NetIncome)
activecell.Value = time.strftime('%a') + ' ' + time.strftime('%m') + '/' + time.strftime('%d')
#HELP FROM HERE
WriteToEmpty()``

There are dozens of ways to acheive what you want. If you have contiguous data in column A you could use something like xl.range("A1").end(xldown).offset(1,0).address to get the address of the first cell in the next empty row. Or you could use xl.range("A1").currentregion and offset from there.
Personally i'd probably just put the current region into an array and work from there, then dump the array back to the sheet, but thats always my preference, most people seem to prefer to work on the sheet.

Related

How to write a python script in Maya with a condition logic

I’m starting as a programmer and currently working on a project but got stuck + have a bit of a brain fart(sorry).
I need to write a tool that will:
1 - set character rig by selecting character in the scene and set script to remember selection.
2 - evaluate whether selected character rig has a namespace or not (depending on that the next step takes different root)
if there is a namespace:
3 - find control in the character rig [namespace] + [side L\R] + [Ctrl]
4 - select target loc and snap one to another then bake animation
if there is no namespace:
3 - find control in the character rig [side L\R] + [Ctrl]
4 - select target loc and snap one to another then bake animation
I wrote parts of the script but don’t know how to put it together because I don’t know how to word this condition in the script.
Can anyone help me to put my brain back in order?
CH = pm.ls(sl=True, fl=True)
for c in CH:
if pm.referenceQuery(c, isNodeReferenced=True):
nameSpace = c.split(':')[0] + ':'
nameS.append(nameSpace)
name = nameSpace + 'L' + '_Weapon_ctrl'
print name
else:
name = 'L' + '_Weapon_ctrl'
print name
def bakeToObj():
Target = pm.ls(sl=True, fl=True)[0]
pm.cutKey(Weapon)
par = pm.parentConstraint([Target] + [Weapon], mo=False)
startTime = pm.playbackOptions(query=True, minTime=True)
endTime = pm.playbackOptions(query=True, maxTime=True)
pm.bakeResults(Weapon, simulation=True, t=(startTime, endTime))
pm.showHidden(above=True)
pm.delete(par)
return bakeToObj
I recommend to continue where you started. The list ist a very good start. Now you can create a script with all functions you need for the list of tasks and one function to call them all, e.g.:
def getSelectedCharacterRig():
sel = pm.ls(sl=True, fl=True)
return sel
def getCtrlName(rig):
....
return ctrlName
def findCtrl(ctrlName):
...
return ctrl
def selectTargetLoc(ctrl):
...
def bake(someObject):
return bakedObject
def doIt():
selection = getSelectedCharacterRig()
ctrlName = getCtrlName(selection)
...
This way you can see what you need an how to do it. And you will see if a function is not needed at all.

Value of string to be a trigger

I'm trying to get my code to get a string of data from a sensor, and then do something when it reads a specific value.
The following code is how I'm receiving the data now (this is just a test) the function is called earlier in the code at the time where I want it to be called.
def gettemperature(self)
temp = self.board.temp_sensor
print("Temperature is " + str(round(temp)) + " degrees.")
This code works, and returns the temperature value rounded to the terminal, but how could I, instead of printing the value to the terminal, make it so when that string of rounded value is say, 200 degrees, then it prints the temperature value? instead of printing it every 2 seconds (the frequency of the data being received, as per another part of the code)
Using something like
if temp = 200
then print(blahblah)
in short, the above code is what I'm trying to do. If the temp equals a certain value, then something else will happen.
That last code doesn't work. I'm pretty new to coding, so I'm assuming I'm either not going about this the right way, or the syntax of how I'm going about trying to get that value to do something isn't correct (obviously)
Thanks for any help! I'm surprised I got this far, haha.
It would be better if your function gettemperature would return something and then print the result in the condition:
def gettemperature()
temp = board.temp_sensor
return temp
temp = gettemperature()
if temp == 200:
print("Temperature is " + str(round(temp)) + " degrees.")
Before using stackoverflow, I'd recommend learning all this stuff from some basic course, as you'll get to learn the stuff yourself rather then get the answer from someone else.
Try learning conditional statements.
what you want is, to put a conditional statement which triggers if temperature is greater than 200.
If the temp is always a number in string data type, you can use the below code.
def gettemperature(self):
temp = self.board.temp_sensor
print("Temperature is " + str(round(temp)) + " degrees.")
temp=int(temp) #typecasting string datatype to integer
if temp == 200:
print("Temperature is high")

Ironpython - how do I refer to to a calculated variable in additional lines of code

I am working with IronPython inside Spotfire.
I need to extract the maximum date value from a range filter, then use that value to filter a table of exchange rates.
I have working code right up to the datatable.Select statement in which I need to do the match. If I do it based on "Date(2020,3,1)" - which is the row commented out - then the match works and the correct result is returned, however I cannot get the syntax correct for using a calculated variable "newdate" in place of the Date(xxx) statement. I am still learning python and have not come across this before.
Code as below - any help would be greatly appreciated.
from Spotfire.Dxp.Application.Filters import RangeFilter, ValueRange
from Spotfire.Dxp.Data.DataType import Date
from System.Globalization import CultureInfo
parser = Date.CreateCultureSpecificFormatter(CultureInfo("en-AU"))
#get a reference to a filter as checkbox from the myDataTable script parameter
filt=Document.FilteringSchemes[Document.ActiveFilteringSelectionReference].Item[dt].Item[dt.Columns.Item["Calendar Date"]].As[RangeFilter]()
print filt.ValueRange.High
if str(filt.ValueRange.High) == "High":
maxdate = Document.Properties["loaddate"]
else:
maxdate = filt.ValueRange.High
maxdate = Date.Formatter.Parse(maxdate)
print maxdate
new = str(maxdate.Year) + "," + str(maxdate.Month) + "," + str("1")
print new
Document.Properties["maxdate"] = new
from Spotfire.Dxp.Data import *
from System.Collections.Generic import List
table=Document.ActiveDataTableReference
# Expression to limit the data in a table
rowSelection=table.Select("CALENDAR_DATE = Date('new')")
#rowSelection=table.Select("CALENDAR_DATE = Date(2020,3,1)")
# Create a cursor to the Column we wish to get the values from
cursor = DataValueCursor.CreateFormatted(table.Columns["FY_AVERAGE_EXCHANGE"])
# Create List object that will hold values
listofValues=List[str]()
# Loop through all rows, retrieve value for specific column,
# and add value into list
for row in table.GetRows(rowSelection.AsIndexSet(),cursor):
rowIndex = row.Index
value1 = cursor.CurrentValue
listofValues.Add(value1)
for val in listofValues:
print val
I think your variable new would print out as 2020,01,01
In this line new is a string so Date() cannot extract a date.
rowSelection=table.Select("CALENDAR_DATE = Date('new')")
You should put new as variable
rowSelection=table.Select("CALENDAR_DATE = Date(" +new +")")
but not sure it'll work as Date takes in Integer not Strings So you might have to re-write to :
y = maxdate.Year
m= maxdate.Month
d = 1
rowSelection=table.Select("CALENDAR_DATE = Date("+ y + ',' + m +',' + d + ")")
or build your String before hand which is the method I would use:
y = maxdate.Year
m= maxdate.Month
d = 1
mystring = "CALENDAR_DATE = Date("+ str(y) + ',' + str(m) +',' + str(d) + ")"
rowSelection=table.Select(mystring)
One of the above ways should work, I'd start with the last one setting your string before as it makes the most sense to not deal with to many conversions of integers and strings.
If you post this question with an example DXP to Tibco Answers could possible help more since will have an example dxp to work with. but hopefully this helps you out.

Stuck in loop help - Python

The second 'if' statement midway through this code is using an 'or' between two conditions. This is causing the issue I just don't know how to get around it. The code is going through a data file and turning on the given relay number at a specific time, I need it to only do this once per given relay. If I use an 'and' between the conditions, it will only turn on the first relay that matches the current time and wait for the next hour and turn on the next given relay.
Could someone suggest something to fix this issue, thank you!
def schedule():
metadata, sched = dbx.files_download(path=RELAYSCHEDULE)
if not sched.content:
pass # If file is empty then exit routine
else:
relaySchedule = str(sched.content)
commaNum = relaySchedule.count(',')
data1 = relaySchedule.split(',')
for i in range(commaNum):
data2 = data1[i].split('-')
Time1 = data2[1]
currentRN = data2[0]
currentDT = datetime.datetime.now()
currentHR = currentDT.hour
global RN
global T
if str(currentHR) == str(Time1):
if T != currentHR or RN != currentRN:
relaynum = int(data2[0])
relaytime = int(data2[2])
T = currentHR
RN = currentRN
k = threading.Thread(target=SendToRelay(relaynum, relaytime)).start()
else:
print("Pass")
Desired Inputs:
sched.content = '1-19-10,3-9-20,4-9-10,'
T = ' '
RN = ' '
T and RN are global variables because the loop is running indefinitely, they're there to let the loop know whether the specific Time(T) and Relay Number(RN) have already been used.
Desired Outputs:
If the time is 9 AM then,
T = 9
RN should be whatever the given relay number is so RN = 3, but not sure this is the right thing to use.
Sorry if this is confusing. I basically need the program to read a set of scheduled times for specific relays to turn on, I need it to read the current time and if it matches the time in the schedule it will then check which relay is within that time and turn it on for however long. Once it has completed that, I need it to go over that same set of data in case there is another relay within the same time that also needs to turn on, the issue is that if I don't use T and RN variables to check whether a previous relay has been set, it will read the file and turn on the same relay over and over.
Try printing all used variables, check if everything is, what you think it is. On top of that, sometimes whietespaces characters causes problem with comparison.
I fixed it. For anyone wondering this is the new working code:
def schedule():
metadata, sched = dbx.files_download(path=RELAYSCHEDULE)
if not sched.content:
pass # If file is empty then exit routine
else:
relaySchedule = str(sched.content)
commaNum = relaySchedule.count(',')
data1 = relaySchedule.split(',')
for i in range(commaNum):
data2 = data1[i].split('-')
TimeSched = data2[1]
relaySched = data2[0]
currentDT = datetime.datetime.now()
currentHR = currentDT.hour
global RN
global T
if str(currentHR) == str(TimeSched):
if str(T) != str(currentHR):
RN = ''
T = currentHR
if str(relaySched) not in str(RN):
relaynum = int(data2[0])
relaytime = int(data2[2])
k = threading.Thread(target=SendToRelay(relaynum, relaytime)).start()
RN = str(RN) + str(relaySched)

local variable 'output_file' referenced before, this code worked a few weeks ago, now it doesnt work how is that possible?

This thing is hard to post code and context inside of.
#This is a menu driven multiplication game. i am attemtping to save the high
#score in a file named multiplication_game.txt...
def single_player():
in_file = open('multiplication_game.txt', 'r')
highest_times_selection = int(in_file.readline())
print('\n____now lets see how u do on the times tables____')
correct = 0
missed = 0
times_selection = int(input(
'\nPlease enter a times time table integer to practice: '))
#This simple generates the multiplation questions and checks for right or
#wrong.
for number in range(0,11):
print(times_selection, 'x' , number, '=')
user_answer=int(input('answer: '))
correct_answer = times_selection * number
if user_answer == correct_answer:
correct+=1
else:
missed+=1
#This is where if its a perfect score and a high times table than the
#previous saved score it should be opened and the new score saved in the
#text document.
if missed == 0 and times_selection > highest_times_selection :
output_file = open('multiplication_game.txt', 'w')
name = input('You have the highest Score!!\n enter your name: ')
output_file.write(str(times_selection)+ '\n')
output_file.write(name + '\n')
else:
print('you missed ', missed, 'and got', correct,'correct\n')
output_file.close()
Try to define output_file = None before any assignment of it.
Tip: before your last if-else condition.
This looks like homework, so I don't want to give you the answer but rather lead you to it.
Take a look at your if/else for your high score table, and walk through your code twice, taking a different branch (different part of the if/else) each time you reach this spot. Write down the variable names on paper as you define them, starting over with a new sheet of paper each time you walk through. If you access a variable, check it off on your list. If you try to access a variable that's not on your list, it's the same as python saying local variable referenced before assignment -- you're trying to access it before you've defined it.
Hope this helps, both in figuring out your problem and learning how to debug in the future.

Categories