This question already has an answer here:
Running Python Script as a Windows background process [duplicate]
(1 answer)
Closed 1 year ago.
I have created a Python script to change my background image based on the time of the day (Windows 10 user).
If the current time it's past the sunset time, then a specific image will be shown, if it's past the sunrise time, then there would be another one.
The sunrise/sunset data is being taken from a published source from an Excel spreadsheet.
What I want is to have this Python code running in the background instead of creating a Task Scheduler job to be ran every 30 seconds. Is there a better way to approach the code below in order to realize this?
from datetime import datetime
import pandas
import ctypes
file_path = "myfile.xlsx"
data = pandas.read_excel(file_path, header=0) #Column lines on line 0
#Today as day number
day = datetime.now().timetuple().tm_yday
#Today's parameters
sunrise = data["sr"][day-1] #sr is a column name in the Excel spreadsheet; Minus 1 to account for 0 based indexing;
sunset = data["ss"][day-1] #ss is a column name in the Excel spreadsheet; Minus 1 to account for 0 based indexing;
#Time right now
now = datetime.now().time()
#Setting up the day_night variable depending on the now variable
if now > sunrise and now < sunset:
day_night = 'day'
else:
day_night = 'night'
#The path to the wallpapers being used
path = 'C:\\wallpapers\\'+ day_night +'.jpg'
SPI_SETDESKWALLPAPER = 20
#Function to change the wallpaper
def changeBG(path):
ctypes.windll.user32.SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, path, 3)
changeBG(path)
Sorry in advance for the messy code. Yesterday was my first day writing code for this kind of purposes.
you can write
pythonw.exe code.py
this will run the code in the background and you will need to turn it off from task manager
if you want this program to start when the computer starts you can place a batch file in shell:startup and write there
pythonw.exe C:\path\To\Code.py
and that's it
Related
I want to download historical intraday stock data. I've found AlphaVantage offers two years of data. It's the longest history of data that I've found for free.
I'm making a script to download the full two years of data for all ticker symbols that they offer and in all timeframes. They provide the data divided in 30 days intervals from the current day (or the last trading day, I'm not sure). The rows go from newest to oldest timedate. I want to reverse the order in which the data appears and concatenate all the months with the column headers appearing only once. So I would have a single csv file with two years of data for each stock and timeframe. The rows of the data would go from oldest to newest timedate.
The problem I have is that I also want to use the script to update the data and I don't know how to append only the data that doesn't already appear in my files. The data that I've downloaded goes from 2020-09-28 07:15:00 to 2020-10-26 20:00:00 in 15 minutes intervals (when they exists, there are some missing). When I use the script again I'd like to update the data. I'd like to delete somehow the rows that already appear and append only the rest. So if the last datetime that appears is for example 2020-10-26 20:00:00 it would continue appending from 2020-10-26 2020-10-26 20:15:00 if it exists. How can I update the data correctly?
Also, when updating, if the file already exists, it copies the column headers which is something I don't want to do. Edit: I've solved this with header=(not os.path.exists(file)) but it seems very inefficient to check if the file exists in every iteration.
I also have to make the script comply with the API's rule of 5 calls per minute and 500 calls per day. Is there a way for the script to stop when it reaches the daily limit and continue at that point next time it runs? Or should I just add a 173 seconds sleep between API calls?
import os
import glob
import pandas as pd
from typing import List
from requests import get
from pathlib import Path
import os.path
import sys
BASE_URL= 'https://www.alphavantage.co/'
def download_previous_data(
file: str,
ticker: str,
timeframe: str,
slices: List,
):
for _slice in slices:
url = f'{BASE_URL}query?function=TIME_SERIES_INTRADAY_EXTENDED&symbol={ticker}&interval={timeframe}&slice={_slice}&apikey=demo&datatype=csv'
pd.read_csv(url).iloc[::-1].to_csv(file, mode='a', index=False, encoding='utf-8-sig')
def main():
# Get a list of all ticker symbols
print('Downloading ticker symbols:')
#df = pd.read_csv('https://www.alphavantage.co/query?function=LISTING_STATUS&apikey=demo')
#tickers = df['symbol'].tolist()
tickers = ['IBM']
timeframes = ['1min', '5min', '15min', '30min', '60min']
# To download the data in a subdirectory where the script is located
modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
# Make sure the download folders exists
for timeframe in timeframes:
download_path = f'{modpath}/{timeframe}'
#download_path = f'/media/user/Portable Drive/Trading/data/{timeframe}'
Path(download_path).mkdir(parents=True, exist_ok=True)
# For each ticker symbol download all data available for each timeframe
# except for the last month which would be incomplete.
# Each download iteration has to be in a 'try except' in case the ticker symbol isn't available on alphavantage
for ticker in tickers:
print(f'Downloading data for {ticker}...')
for timeframe in timeframes:
download_path = f'{modpath}/{timeframe}'
filepath = f'{download_path}/{ticker}.csv'
# NOTE:
# To ensure optimal API response speed, the trailing 2 years of intraday data is evenly divided into 24 "slices" - year1month1, year1month2,
# year1month3, ..., year1month11, year1month12, year2month1, year2month2, year2month3, ..., year2month11, year2month12.
# Each slice is a 30-day window, with year1month1 being the most recent and year2month12 being the farthest from today.
# By default, slice=year1month1
if Path(filepath).is_file(): # if the file already exists
# download the previous to last month
slices = ['year1month2']
download_previous_data(filepath, ticker, timeframe, slices)
else: # if the file doesn't exist
# download the two previous years
#slices = ['year2month12', 'year2month11', 'year2month10', 'year2month9', 'year2month8', 'year2month7', 'year2month6', 'year2month5', 'year2month4', 'year2month3', 'year2month2', 'year2month1', 'year1month12', 'year1month11', 'year1month10', 'year1month9', 'year1month8', 'year1month7', 'year1month6', 'year1month5', 'year1month4', 'year1month3', 'year1month2']
slices = ['year1month2']
download_previous_data(filepath, ticker, timeframe, slices)
if __name__ == '__main__':
main()
You have an awful lot of questions within your question!
These are suggestions for you to try, but I have no way to test the validity of them:
Read all your files names into a list check files names exist against the list rather than pinging the os each time
Read the data from existing file and append everything in pandas and write new file. Can't tell if you are appending the csv files but if you're having difficulty there just read the data and append new data - until you figure out how to append a excel correctly. Or save new iterations to their own file and consolidate files later.
Look into drop_duplicates() if you have concerned with having duplicates
Look into time module for time.sleep() in your for loops for reduce calls
If you have 1min data you can look into resample() to 5min, 15min rather than importing at all those timeframes
Ahoy! I've written a quick (Python) program that grabs the occupancy of a climbing gym every five minutes for later analysis. I'd like it to run non-stop, but I've noticed that after a couple hours pass, one of two things will happen.
It will detect a keyboard interrupt (which I did not enter) and stop, or
It will simply stop writing to the .csv file without showing any failure in the shell.
Here is the code:
import os
os.chdir('~/Documents/Other/g1_capacity') #ensure program runs in correct directory if opened elsewhere
import requests
import time
from datetime import datetime
import numpy as np
import csv
def get_count():
url = 'https://portal.rockgympro.com/portal/public/b01ab221559163c5e9a73e078fe565aa/occupancy?&iframeid=occupancyCounter&fId='
text = requests.get(url).text
line = ""
for item in text.split("\n"):
if "\'count\'" in item:
line = (item.strip())
count = int(line.split(":")[1][0:-1]) #really gross way to get count number for this specific source
return count
while True: #run until manual stop
with open('g1_occupancy.csv', mode='a') as occupancy:
occupancy_writer = csv.writer(occupancy)
occupancy_writer.writerow([datetime.now(), get_count()]) #append new line to .csv with timestamp and current count
time.sleep(60 * 5) #wait five minutes before adding new line
I am new to web scraping (in fact, this is my first time) and I'm wondering if anyone might have a suggestion to help eliminate the issue I described above. Many thanks!
I have a Jupyter Notebook. Here is just a simplified example.
#Parsing the website
def parse_website_function(url):
return(value,value2)
#Making some calculations(hypothesis)
def linear_model(value, value2):
return(calculations)
#Jot down calculations to csv file
pd.to_csv(calculations)
I would like to know how to make it work every hour and enable to rewrite(add new rows) to csv time series data in the same output file. Thanks!
A really basic way to do this would be to just make the program sleep for 3600 seconds.
For example this would make your program pause for 1 hour:
import time
time.sleep(3600)
Essentially I am trying to make a little app for the people I work with to automatically fill out our weekly timesheet's. It will ask you your name, which days you worked, how long for(inc overtime) and populate this data into a pre-made excel spreadsheet made by the various companies we work for.
So to start I am just learning how to edit cells with the input from the user.
My issue during my quick tests - in a blank excel document when I run wb.save(test.xlsx) it will update it with my changes but it makes all the colours go funky for some reason (image attached)
Im not quite sure why it's doing this - I tried googling but all I could find was info on how to change the colour of the rows not anything relating to my problem. It's probably something really obvious but I thought I would ask anyway.
Really appreciate any help!
Edit - attached code -
# Timesheet Bot v1.0
import os
import sys
import openpyxl
from openpyxl.styles import colors
from openpyxl.styles import Font, Color
from openpyxl import Workbook
path = ('/Users/namehere/Desktop/Test')
os.chdir(path)
wb = openpyxl.load_workbook('example.xlsx')
sheet = wb['Sheet 1']
print ('')
print ('')
print ('')
print ('')
print ('Hello and Welcome to Timesheet Bot 1.0 - I am Roger')
print ('I will sort out your Timesheet(s). Lets get started!')
print ('')
print ('\033[91m' + "I now will ask you a few questions about your work week." + '\033[0m')
print ('')
print ('')
print ('')
name = str(input('What is your full name? '))
sheet['C4'] = name
weekending = str(input('What is the week ending date ? (Sunday and must be DD/MM/YY) '))
sheet['C5'] = weekending
start = int(input('What was the start time for the week?'))
sheet['C7'] = start
sheet['C8'] = start
sheet['C8'] = start
sheet['C9'] = start
sheet['C10'] = start
sheet['C11'] = start
end = int(input('What was the end time for the week?'))
sheet['D7'] = end
sheet['D8'] = end
sheet['D8'] = end
sheet['D9'] = end
sheet['D10'] = end
sheet['D11'] = end
wb.save('example.xlsx')
I guess that you've already found a workaround by now, but I just ran into the very same problem and found the underlying issue.
This happens specifically to files that are created with Apple Numbers. If you use any colors in Numbers, the color information gets saved into a global color palette. Unfortunately the palette information gets lost when saving the data to a new file in openpyxl, so your spreadsheet software will fall back to the default palette.
I've opened a pull request that should fix the issue.
I am trying to write a function that can find files from a certain date and before and delete them. I was playing around with fabric and I want to delete my old log files from my server. the folder has files in the following format:
['user-2015-10-16.log.gz', 'user-2015-10-19.log.gz', 'user-2015-10-22.log.gz', 'user-2015-10-25.log.gz', 'admin-2015-10-17.log.gz', 'admin-2015-10-20.log.gz', 'admin-2015-10-23.log.gz', 'requests.log', 'user-2015-10-17.log.gz', 'user-2015-10-20.log.gz', 'user-2015-10-23.log.gz', 'extra.log', 'admin-2015-10-18.log.gz', 'admin-2015-10-21.log.gz', 'admin-2015-10-24.log.gz', 'user-2015-10-18.log.gz', 'user-2015-10-21.log.gz', 'user-2015-10-24.log.gz', 'admin-2015-10-16.log.gz', 'admin-2015-10-19.log.gz', 'admin-2015-10-22.log.gz', 'admin-2015-10-25.log.gz']
What I want to do is keep files from today till 4 days back i.e. keep the ones from 25th, 24th, 23rd, 22nd and delete the rest (keep extra.log and requests.log).
I tried this:
import datetime
days = 4
user = []
admin = []
for i in range(days):
that_date = datetime.datetime.now() - datetime.timedelta(days=i)
use = 'user-{}.log.gz'.format(that_date)
adm = 'admin-{}.log.gz'.format(that_date)
# user.append(user)
# admin.append(admin)
print user, adm
But realized embarrassingly late that this gives me the files I want to keep and not the ones I want to delete.
Any help will be greatly appreciated
Edit: if not already clear, the files are generated daily with the user-(todays date) format so cant hardcode anything.
You might consider using glob with user-* and admin-* and then get the file creation times with os.stat
NOT TESTED, but something like:
import glob
import os
import time
target=4*24*60*60 # 4 days in seconds
for fn in glob.glob('user-*')+glob.glob('admin-*'):
if time.time()-os.path.getctime(fn)>target:
# delete that file...
You need to change the working directory (or change the glob) to the target directory.