Showing posts with label Productivity. Show all posts
Showing posts with label Productivity. Show all posts

Friday, February 21, 2014

Tablet and Google Hangouts Screenshare as KVM secondary monitor

Main display on KVM showing Linux workstation,
while monitoring Mac on tablet
I use a single 30" monitor while working across several workstations, but I'd like to know when some long running operations (e.g. building Chrome, or running tests) complete. Robert Ginda suggested using a spare tablet and Google video hangouts with screenhare. Works great!

- From source machine: open a hangout with yourself (I typed my own email address into the gmail hangout panel)

- Start a video chat, and from there a screenshare.

- Open hangouts on phone or tablet, join the existing video chat, have a second view!

- Flip back to other workstation on main display while you wait.

Sunday, October 9, 2011

Gmail Follow Up Script

I have lots of email I want to follow up on later or put aside for some time. I use Gmail these days, and I miss Outlook's built in feature for this. Well, there's a solution, the apps script team posted a script for "snoozing" email. My modified take on it is this gmail Follow Up script doc.

With follow up you can:

  • Get emails out of your inbox, and out of sight, for a specified amount of time, and then have them return.
  • Send emails you want to make sure you get a response on, flag them for follow up and have them resurface in your inbox again after a given amount of time to ensure they were handled.


The implementation summary is: You can have javascript code run on a Google server at a regular interval that manipulates your gmail messages. You do so with google apps script.

I modified the original in a few ways:

  • I added "hours" to the "days" and "weeks"
    • At first I thought it was overkill. But, no, it's mighty handy in a work day to put off an email till the afternoon when you think someone else should have replied by then. Or just to clear your inbox rapidly so you can concentrate on the top items for the next hour.
  • I adjusted the label names to be more keyboard shortcut friendly
    • To move an item out of my inbox and have it reappear tomorrow, I type the keys, "v1d" enter. That's |move|, and then enough to match the label "FollowUp-1days".
  • I use the "quick links" lab in gmail to view all messages pending follow up
    • Sadly there's no way to roll up multiple labels in gmail, else the hierarchical labeling would have solved this. Anyway, details in the doc for using quick links.
Some notes:
  • Draft messages can be brought back to to the inbox, to complete and or send at a later time.
  • Muted messages can be brought back too, disabling the mute at that time. So you can let a firestorm thread rage on for a few hours before reviewing it in it's entirety instead of being interrupted constantly as replies come in.
  • I sometimes leave notes to myself as to why I marked this message for follow up. One way is to start a reply draft and then blank out the To: line so it's not accidentally sent.
  • It's handy when you send a message and want to ensure you get a reply back.
Now that I have this tool, I use it a lot a lot to rapidly simplify my inbox. Check it out: Follow Up script

Thursday, January 20, 2011

Tools of a Day

I use these tools daily:
How about you, anything interesting?

Sunday, December 5, 2010

How to Share an Email Address in Gmail

My wife and I each have our own email addresses. Common, though she is irked by a few friends who don't. They can only be emailed by sending to the joint "family" email, often actually just the husband's name. Trust issues? Anyway...

Having a joint account is handy now and then. I want one. They're good for things like that real estate agent who just can't figure out "reply all", or that web site that only allows one email address to be entered you both want to track.

Bad news, I didn't find a perfect answer. Good news, I found one good enough... only you and your significant other can mess it up, and only slightly:

Set up a new gmail account, have it forward to each of you. Set up your gmail account to be able to send as the joint account when you choose.

Walk through:
  • Create a new gmail account wife.and.i@gmail.com by going to gmail when you're not logged in. (or use an incognito window in chrome)
    • In Settings/Forwarding, add forwarding addresses for your existing accounts, wife@gmail.com and me@gmail.com
    • In Settings/Filters, add a filter to match everything. This is a tad tricky, you can't just use From: *. So, create a filter that Doesn't have: some_long_random_string_sldkfjslkdjfsdfkjsdf and then select one account to forward to. Repeat, creating a new filter, for the second account.
  • Configure your personal account (me@gmail.com, repeat for wife@gmail.com) to be able to send and reply from the joint account.
    • in Settings/Accounts in the "Send mail as:" section, add wife.and.i@gmail.com
    • On the same page, select "Reply from the same address the message was sent to"
It works: 
    • Easily give the shared email address wife.and.i@gmail.com to anyone and you'll both receive the emails in your personal accounts without needing to ever log into wife.and.i@gmail.com again.
    • Replying to an email sent to the joint account will "just work" and appear to come from the joint account. (But, don't forget to CC your significant other if you want them to see your reply)
    • Writing a new email as if it came from the joint account is easy too:
      • Compose a new message, above the To: is the From: address, and you can change it to the joint account.
      • (But, don't forget to CC your significant other if you want them to see your reply)
    What's tedious is that you must remember to CC your other every time. Now, we're all high and mighty about external people who can't remember to reply-all, so we should be able to remember to CC everyone each time, right? Still... tedious. If you forget, at least the reply from the external people will go back to both of you.

    Here are the other things I tried:
    • Create an outgoing filter to automatically forward to your significant other's account?
      • Nope, you can filter outgoing email (adding labels, say), but you can't forward them.
    • Create an outgoing filter to label and remind you that you forgot to CC?
      • Nope, you can add a label, but not send it to the inbox also or mark it unread, so no way to get attention.
    • Create a group on googlegroups.com?
      • Nope, you can send and reply as the shared email, but you must manually CC your significant other's account each time. The group account doesn't appear in a reply all because you're sending as that account. If you're not sending as that account it works, yay, but then you're sending as just you, and replies will not go to the joint account.
    Have a better solution? Lemme have it in the comments!

    Tuesday, July 14, 2009

    An Email Organization Scheme for Outlook 2007: How I Efficiently Triage Email


    I process a lot of email. (Beautiful pixels take a lot of email to make these days.)

    Many emails are in conversation threads. Some emails are very important, and must be responded to, while others I can soak up when I have time or choose to skip over.

    I'll discuss the system I use in Microsoft Outlook 2007.

    Here's what it looks like:



    The mechanics of it:
    • I leave email marked Unread until I explicitly mark it read (CTRL-Q)
      • I turn off automatic marking as read (Menu: Tools: Options: Other Tab: Reading Pane...)
    • I flag message for Follow Up (with times, e.g. Today, Tomorrow, Next Week, or a specific date).
    • I read email from the "Unread or For Follow Up" folder.
      • (You'll find this under your Mailbox tree, in "Search Folders")
      • This displays all messages not yet read, or flagged for follow up.
    • I use a custom view:
      • Make a a new view by copying one and making changes
        • Menu: View: Current View: Define: Copy "Messages with Auto Preview"
      • Group By...
        • (set "Select available fields from" to "All Mail fields")
        • Start Date (Ascending)
        • Importance (Descending)
        • In Folder (Ascending)
        • Conversation (Ascending)
      • Sort...
        • (set "Select available fields from" to "All Document fields")
        • Category (Ascending)
        • Received (Ascending)
        • (say "No" when closing window and asked if you want to show Category field)
      • Other Settings
        • Auto Preview: Preview unread items
        • Reading Pane: Right
      • Automatic Formatting...
        • Only Me
          • Condition: Where I am "the only person on the To line"
          • Font: Underline
    • I make important email folders "Favorites"
    • Our teams use many public folders, and I make them favorite folders for the ones I track
      • (You must make the public folder a favorite public folder, then a favorite email folder)
    • I use several rules to presort items
      • Route emails to topic specific folders whenever possible
        • e.g. sales staff, partner companies, email lists
      • Flag items for follow up later
        • e.g. items I need to review weekly are flagged "next week"
        • Delete means "trash it, I don't need it any more, but just in case keep ~6 months of deleted items"
      • I purge deleted items manually
    • My Inbox means "I haven't bothered to sort this", and accumulates lots of email
      • I don't read out of the inbox, so it doesn't matter much if it builds up
      • I do periodically move everything in the inbox to a folder "_save-generic"


    Now, how do I use this?
    • Emails arrive and I triage them.
      • I select the "Unread or For Follow Up" folder.
      • I hit the Home key to get to the top.
      • I scan over the large pile of unread messages, and first at a quick glance:
        • Delete anything obviously not important.
        • Move to Folder anything that should be sorted
          • This greatly improves grouping of items in this "Unread or For Follow Up" view, beyond just filing things away for later.
          • I use the toolbar icon which remembers the most recent folders I've put things into.
        • Mark as read (CTRL Q) anything trivial I can ignore .
        • Flag for follow up anything substantial I can't handle right now.
          • Tomorrow, this week, next week, or a specific calendar day if needed..
        • Anything remaining I need to handle right now.
          • I flag these by just clicking on the "flag", which is effectively "Today".
        • My email I should handle is now all sorted by a follow up date.
        • I hit F5 to refresh the view - hiding all messages marked Read and with no flag.
    • After triage, emails are displayed in groups sorted by the time frame I need to review them.
      • I read emails, and after doing so mark them as read, leaving them flagged if I still need follow up.
      • As emails are dealt with, I delete them if appropriate, or click their flag to mark them as complete (which removes them from this list).
      • I can easily push items futher away in time if I'm getting backed up, or "read ahead" if I'm ahead of things


    The major benefits:
    • I can easily push items into the future and not deal with them right now - they'll come back to my view at an appropriate time.
    • Long conversations are all grouped together, automatically. And they can easily be hidden/rolled up from the view.
    • I can easily sort several emails into folders, which groups them together in my view. Thus related emails can be grouped together, even when they have unrelated subjects lines.
    • Public folders allow me to go to that topic at an appropriate frequency (every few hours, daily, weekly), and making them favorite favorites makes them easy to see.
    • New High Importance emails are at the top of the list, while ones I've look at can be pushed down for later.
    • Emails will never "fall through the cracks".


    The shock to new users:
    • The email view is padded out vertically quite a bit.
      • True, but the sorting and grouping benefits are worth it when you're tracking dozens to hundreds of emails.
      • You get used to it pretty quickly.
      • For select folders I use a different view that has 1 email per line. You can always toggle 2 views for your need.
    • Explicitly marking all emails as read is a pain.
      • Multi-select and marking entire conversations read at a time helps.
      • This is what keeps emails from falling through the cracks.

    - thanks technabob.com for the cc image of the hamster shredder.

    Monday, January 12, 2009

    Vista Send To Clipboard As Name

    Vista 64bit has been a fairly smooth move for me, but one feature of Windows XP I missed dearly was Send To Clipboard As Name (from the Power Toys).

    I frequently have one or several files I'd like to get as fully qualified text strings to dump into a shell command, another application, or just a text file when keeping notes.

    Well, I found it, Vista supports Copy as Path on a file explorer context menue if you hold SHIFT when opening the context menu.

    The image shows the context menu with the SHIFT exposed items:
    • Pin to Start Menu
    • Add to Quick Launch
    • Copy as Path

    Tuesday, January 6, 2009

    msinfo32 - big brother of dxdiag

    Developers likely already know about dxdiag, a good tool to get information related to graphics. However, did you know about msinfo32?

    Msinfo32 and it's predecessors (msd, winmsd) have shipped with DOS and Windows for quite some time. These tools are a great one-stop-shop to get information about a machine: device memory mappings, drivers, environment variables, startup programs, history of program crashes, etc...

    Msinfo32 is easy to launch and save a computer's data to a single binary or export to a text file, which you can examine on other computers. Handy to know about when you're debugging across several machines.

    Thursday, December 18, 2008

    Coder Tip: Loading symbols in Visual Studio 2008 the easy way.



    Bo Wilson keyed me in to this Visual Studio 2008 (VC90) Tip:
    • Debugging through some code touching Microsoft libraries (e.g. DirectX)?
    • Wish you had symbols, but too lazy to set them up again, cache them, wait for them all to download, blah?
    • Visual Studio 2008 makes it easy:
    • Just open the Modules window (Debug, Windows, Modules)
    • Right click a DLL, and load symbols from the Microsoft Symbol Servers.

    Thursday, December 11, 2008

    Link dump: Genetic Polygons, Scored Gameplay, ActiveX alternative, Gamebryo Training, Visualizing Files, Opening Files

    Genetic algorithm placing 50 polygons to represent the Mona Lisa
    I'm a fan of genetic algorithms... I'd have loved to see this one with triangles instead of n-polygons, though.

    This image is early in the evolution, the final image is a good approximation. ;)
    Reset
    A fun, short, game. Cool novelty: the gameplay is synchronized with the music. Friend Adrienne Walker pointed out that this could be a great game jam theme.
    Google Native Client
    A plugin recently revealed by Google.
    Cross browser, runs sand boxed native code.
    Could be a good alternative to ActiveX.
    Gamebryo 101
    A university created webpage packed full of training videos, tutorials, and resources related to the product I work on.

    WinDirStat
    I recently gave up on SpaceMonger -- it was having issues with lots of files. This survey convinced me to move over to WinDirStat, which works very well.

    Mr EditGotoFindCombo
    Nice tip for Visual Studio programmers:
    Quickly open files with sub-string prefix matching:
    CTRL-D, type:">of ", then start your file name.
    More tips on the linked page.

    Friday, September 19, 2008

    Testing Build Times with RAID 0 on a Dell Precision

    Machines from Dell can easily be configured with a RAID controller these days. I was curious to see: Would using RAID-0 (striping) improve build times? The short answer: no.

    On one hand, I'm not surprised. On the other, I really wanted to give it a true scientific test, with real parts and a real workload. It's so easy to purchase machines configured this way, we might as well be buying machines in an optimal config.

    I've been wanting to run this test scientifically for a while now. So I jumped on a new Dell Precision T5400 that had been ordered, and had it configured with a second hard drive (320GB SATA 3.0Gb/s, 7200RPM HardDrive with 8MB DataBurst Cache).

    I installed Vista, Developer Studio 2008, DirectX August 2008, and Gamebryo 2.5. I built the Debug configuration of the first sizable solution (CoreLibs) which contains 11 fairly small libraries. Then I did it all again with a RAID0, 128kb block size. Build times were equivalent at 1 minute 15 seconds.

    Now, I'm a graphics guy, not a hardware guy -- so maybe I overlooked something. If so... ;) let me know. I'll hold off a few days before I build up this machine for production use. At the moment, I'm planning on not using a RAID configuration.

    Sunday, April 27, 2008

    Depend on Dependency Macros for Visual Studio Project Dependencies


    [update: fixed code typo]

    I set dependencies on visual studio projects frequently. Here is some macro code that simplifies that process.

    At the last 2 studios I joined one of the first things I did was to make an "All" solution. A single visual studio solution containing all projects required to build the game (or in Gamebryo's case, engine, samples, & tools).

    A nice big solution like that needs to have dependencies set right. Visual Studio's interface for doing this is inefficient for anything but toy "solutions". But, they gave us macros, and it's easy to set dependencies with those.

    Example solution file, with projects broken into logical groups

    With these macros, you first select a group you would like to change the dependency information for. Run macro Step1. Then, select the group of projects that all the previous projects depend on. You'll then see this window:
    Macro Dialog confirming dependencies about to be set.

    Setting dozens or hundreds of project dependencies is a breeze with these macros.

    Here's the code (Visual Studio 2005 macros, aka VS8):


    Imports System
    Imports EnvDTE
    Imports EnvDTE80
    Imports System.Diagnostics

    ' Need List:
    Imports System.Collections.Generic

    Public Module Module1
    Sub Step1_SelectDependentProjects()
    'DESCRIPTION: Step 1 of 2 for setting dependencies on projects
    SelectedProjects = GetSelectedProjects()
    Dim OutputString As String
    OutputString = SelectedProjects.Count.ToString
    OutputString += " Selected Projects:" + vbLf
    OutputString += GetStringOfEachProject(SelectedProjects)
    MsgBox(OutputString)
    End Sub

    Sub Step2_SelectDependeeProjects_AssignDependencies()
    'DESCRIPTION: Step 2 of 2 for setting dependencies on projects
    If SelectedProjects Is Nothing Then
    MsgBox("You must first select projects to have dependencies set on, with SelectDependentProjects macro")
    Return
    End If

    Dim DependentProjs As List(Of EnvDTE.Project) = SelectedProjects
    Dim DependeeProjs As List(Of EnvDTE.Project) = GetSelectedProjects()

    Dim OutputString As String
    OutputString = "Are you sure you want to set" + vbLf + vbLf
    OutputString += DependentProjs.Count.ToString + " Projects:" + vbLf
    OutputString += GetStringOfEachProject(DependentProjs) + vbLf + vbLf

    OutputString += "As dependent upon" + vbLf + vbLf
    OutputString += DependeeProjs.Count.ToString + " Projects:" + vbLf
    OutputString += GetStringOfEachProject(DependeeProjs) + vbLf + vbLf

    If MsgBox(OutputString, MsgBoxStyle.OkCancel) = MsgBoxResult.Cancel Then
    Return
    End If

    For Each Dependent As EnvDTE.Project In DependentProjs
    For Each Dependee As EnvDTE.Project In DependeeProjs
    Try
    DTE.Solution.SolutionBuild.BuildDependencies.Item(Dependent).AddProject(Dependee.UniqueName)
    Catch ex As System.Exception
    Dim Result As Microsoft.VisualBasic.MsgBoxResult
    Result = MsgBox("Failed to add dependency: " + vbLf _
    + "Dependent: " + Dependent.Name + vbLf _
    + "on" + vbLf _
    + "Dependee: " + Dependee.Name + vbLf + vbLf _
    + "Error is:" + vbLf + ex.Message + vbLf + vbLf _
    + "CONTINUE????", MsgBoxStyle.YesNo)
    If Result = MsgBoxResult.No Then
    Return
    End If
    End Try
    Next
    Next
    MsgBox("Done.")
    End Sub

    ' Storage for list of projects:
    Public SelectedProjects As List(Of EnvDTE.Project)

    ' Helper functions:
    Function GetSelectedProjects() As List(Of EnvDTE.Project)
    Dim projs As List(Of EnvDTE.Project) = New List(Of EnvDTE.Project)
    For Each selectedItem As EnvDTE.SelectedItem In DTE.SelectedItems
    Try ' to get projects
    If Not selectedItem.Project Is Nothing Then
    If Not projs.Contains(selectedItem.Project) Then
    projs.Add(selectedItem.Project)
    End If
    End If
    Catch
    End Try
    Next
    Return projs
    End Function

    Function GetStringOfEachProject(ByVal ProjectsList As List(Of EnvDTE.Project)) As String
    Dim OutputString As String = ""
    For Each proj As EnvDTE.Project In ProjectsList
    If OutputString.Length > 0 Then ' add new line
    OutputString += vbLf
    End If
    OutputString += " " + proj.Name
    Next
    Return OutputString
    End Function

    End Module

    Saturday, April 12, 2008

    An Inline ASCII Bar Chart Technique for Spreadsheets

    Here's an article with a neat inline ASCII bar chart technique for spreadsheets.

    So, you're a programmer, game designer, artist, producer, or... just about anyone. Chances are you've used Excel. You may even use it to look at data!

    Look, here's some generic data (Fig. 1):

    Wouldn't it be much easier to look at with a chart? Why not build a chart right into the spreadsheet, along side the data (Fig. 2):
    Note the bar graphs adjacent to the data columns from above

    Real data may have 100s or 1,000s of rows, with several columns. Being able to skim through the spreadsheet and have the data graphically represented inline is often a big win for readability and locality.

    The technique is simple. Excel has a formula to repeat a string several times. For the "Range" graph, the formula is just =REPT("#", D). This works out nicely because the values are integer and small.

    The "Value" data takes just a bit more work, but is still trivial to write. Here I've used =REPT("|", F6*20), (Fig. 3)

    With just a bit more work, we can setup a nice general formula that can be tweaked for each data range, and is more robust. Also, setting the font of the graph to "Small Fonts" with a point size of 4 give us single pixel accuracy in our bar chart, see (Fig. 4).

    Note the broken bar indicating overflow for the first 2 lines,
    the easily configurable min max range,
    and the single pixel accuracy of the bars.

    Each row of the bar chart uses the formula:
    =LEFT(CONCATENATE(REPT("|",E$57-1),">"),MAX(0,(D34-E$53)/(E$55-E$53)*E$57))

    Let me break it down:

    I'm going to substitute names instead of cell references, so it's easier to follow along:
    (If you don't know about them, try selecting a cell and using Insert/Name/Define and Insert/Name/Apply some time. But, it's out of the scope of this article)

    Ok, the formula is then:
    =LEFT(CONCATENATE(REPT("|",Chars-1),">"),MAX(0,(DataValue-Min)/(Max-Min)*Chars))

    First, we want to map the data values between Min and Max to appear on the bar chart, so we normalize to 0-1 range:
    =LEFT(CONCATENATE(REPT("|",Chars-1),">"),MAX(0,(DataValue-Min)/(Max-Min)*Chars))

    Then, multiply by the max number of characters we want a bar chart line to have:
    =LEFT(CONCATENATE(REPT("|",Chars-1),">"),MAX(0,(DataValue-Min)/(Max-Min)*Chars))

    Then, we want to clamp to positive numbers only, so that data values less than our minimum value don't break our graph:
    =LEFT(CONCATENATE(REPT("|",Chars-1),">"),MAX(0,(DataValue-Min)/(Max-Min)*Chars))

    That gives us the number of characters to display. But, we would like to visually show when the data values are larger than the bar chart can show. So, instead of taking the number so far and giving it to REPT, we give it to LEFT. Left will take N characters from a string, and we'll terminate that string with a > symbol to show that the graph is maxing out. The equation could be as such:
    =LEFT("|||||||||||||||||||||||||||||>",MAX(0,(DataValue-Min)/(Max-Min)*Chars))

    But, hard-coding the number of characters on the graph is a draw back. We want to be able to copy and paste this solution around, and scale the graph up as needed. So, we use REPT to generate the |||||||| characters, and concatenate with the final >
    =LEFT(CONCATENATE(REPT("|",Chars-1),">"),MAX(0,(DataValue-Min)/(Max-Min)*Chars))

    The controls for the graph can be put in the column of the graph above or below the data. We can easily have several columns of bar charts, each with tunable parameters.

    I use this technique frequently, I hope you keep it in mind (at least the simple version) the next time you're trolling over data in Excel.

    Wednesday, March 26, 2008

    Perforce tool: p4shelf


    Perforce is the source control solution du jour. It's great, except for a few frustrating gaps in features.

    One of those gaps is the ability to quickly and easily set aside the work you were doing. Here's a nice script that solves that, called p4shelf.

    The author has several other good p4 tips as well, on his blog Aurora.

    The next most frustrating aspect of p4 to me is the inconsistency of integrating file changes vs file creation/deletion. It is easy to integrate changes you've made to a series of files. However, when you've added or removed files between branches, suddenly your integrations are much more complex. You can not, for example, choose to ignore a file deletion.