Пример #1
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# randomevent.py
# rosevomit.programlogic.randomevent
# ___________________________________________________________________
"""A file that contains functions for randomly generating annual events."""
import os
import random

from core import logs

_RANDOMEVENTLOGGER = logs.BaseLogger(__name__)


def check_volcano(ARG_in_year, ARG_csv_destination=""):
    """Checks to see if a volcano explodes. Returns text to display onscreen, and also possibly writes some data related to each event to the specified file.

    Parameters
    ----------
    ARG_in_year
        "...in this year, something happened..."
    ARG_csv_destination (defaults to "")
        The file to store results in. Should include '.csv' extension.
    """
    # Validating arguments
    if os.path.isfile(f"{ARG_csv_destination}") is True:
        _write_to_file = True
    else:
        _write_to_file = False
    if isinstance(ARG_in_year, int) is False:
        in_year = -1
Пример #2
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# dialogexit.py
# rosevomit.programcli.dialogexit
# ___________________________________________________________________
"""A UI module that contains the dialog for exiting the program."""
import sys

from core import logs
from programcli import _dialog

_EXIT_DIALOG_LOGGER = logs.BaseLogger (__name__)


def simple_exit_dialog():
    """This function displays a message asking the user to confirm the program exit. Accepts no parameters, returns nothing."""
    print ()
    do_we_exit: bool = _dialog.prompt_yesno (ARG_prompt="Are you sure you want to exit?")
    if do_we_exit is True:
        sys.exit(0)
Пример #3
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# randomname.py
# rosevomit.programlogic.randomname
# ___________________________________________________________________
"""A file that contains functions for randomly generating names."""

import os
import random

try:
    from core import directories, logs
except ImportError:  # for external unit testing
    from rosevomit.core import directories

_RANDOMNAMELOGGER = logs.BaseLogger(__name__)


def one_file(ARG_file1) -> str:
    """A function that returns one random line from a text file 'ARG_file1'.

    Parameters
    ----------
    ARG_file
        The file to draw a random line from.

    Returns
    -------
    str
        A random line from 'ARG_file'.
    """
Пример #4
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# tempfiles.py
# rosevomit.core.tempfiles
# ___________________________________________________________________
"""A logic module that handles files in the /temp directory."""
import os
import pathlib
import shutil
import textwrap

from core import logs
from core.customerrors import RealityError
from core.constants import TEMP_DIRECTORY_PATH

_TEMPFILELOGGER = logs.BaseLogger(__name__)


def _check_that_cwd_is_temp():
    """Checks to see if we are in the temp directory. Accepts no parameters, returns nothing."""
    with pathlib.Path.cwd() as cwd:
        p = pathlib.PurePath (cwd)
        if p.parts[-1] != "temp":
            print ("POSSIBLE ERROR:")
            print (textwrap.fill ("We should have found Rosevomit's /temp firectory, but we seem to have gotten lost instead."))
            print ("CURRENT LOCATION:")
            print (cwd)
            print ()
            input ("Press any key to continue.")
            raise FileNotFoundError
Пример #5
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# about.py
# rosevomit.core.about
# ___________________________________________________________________
"""This file contains general information about Rosevomit, as well as information about the tools and programs it was developed with or depends on."""
from core import logs

_ABOUT_LOGGER = logs.BaseLogger(__name__)

LICENSE = (
    "MIT License",
    "Copyright (c) 2019 Alexander Lemna",
    'Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:',
    "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
    'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.',
)
PROGRAM = (
    "Rosevomit exists primarily as a hobby/self-learning project for its original developer, Alex Lemna, and is only incidentally intended to be useful to others. The fact that it is open-source and (hopefully) well-documented doesn't mean that its developer knows what he is doing. If you have some spare time and see some mistakes or areas that could be improved - fork it and open a pull request!",
    "Rosevomit is written in Python 3, a free (like speech and beer) high-level programming language. A programming language is a specification of rules and syntax that makes it easier for humans to talk to computers, and most programming languages can have multiple 'implementations' or ways of translating their human-readable program into machine code. In my case, I used the CPython implementation of Python - but if you try to run this program's source code on another Python implementation like PyPy, it should be able to run just fine.",
)
Пример #6
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# constants.py
# rosevomit.core.constants
# ___________________________________________________________________
"""This file contains constants that will be used throughout Rosevomit."""
from pathlib import Path
import re

from core import _dynamic_constants, logs

_CONSTANTSLOGGER = logs.BaseLogger(__name__)

# ---------- STATIC CONSTANTS ----------
# These constants are explicitly defined in the code.

SEE_ROSA_RUN: bool = True

_CORE_DIRECTORY_NAME = "core"
LOG_DIRECTORY_NAME = "core/logdata"
CLI_DIRECTORY_NAME = "programcli"
LOGIC_DIRECTORY_NAME = "programlogic"
DATA_DIRECTORY_NAME = "programdata"
TEMP_DIRECTORY_NAME = "temp"
SAVE_DIRECTORY_NAME = "saved"

# --- Lists of RegEx for parsing user input ---
REGEXES_YES: list = [
    re.compile(r"^[Y][ES]*$", flags=re.IGNORECASE),
]
REGEXES_NO: list = [
Пример #7
0
# ___________________________________________________________________
# suncal_helpers.py
# rosevomit.programlogic.suncalc_helpers
# ___________________________________________________________________
# pylint: skip-file
"""A file that contains helper functions for the main suncalc function contained in 'suncalc.py'."""
import csv
from decimal import Decimal
from math import asin, atan2
from math import pi
from typing import IO

from core import logs
from core.utilities import Angle, deg2rad, rad2deg, angle_sanity_check

_SUNCALCHELPER = logs.BaseLogger(__name__)

# defaults
AXIAL_TILT = 10  # Note that axial tilt is also called "obliquity of the ecliptic"


def antikythera_rotation_angle (astrodate):
    """Returns the 'Antikythera Rotation Angle', equivalent to Earth's 'Earth Rotation Angle' and similar to Earth's 'Greenwich Sidereal Time', though Earth's GST includes an adjustment for the procession of Earth's March equinox that is irrelevant for Antikythera.

    Parameters
    ----------
    astrodate
        The fractional day of the year.

    Returns
    -------
Пример #8
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# saving.py
# rosevomit.programlogic.saving
# ___________________________________________________________________
"""This file handles Rosevomit's filesaving behavior."""
from typing import Callable
from core import logs
import core.utilities as ut
from programcli import dialogsave

_SAVELOGGER = logs.BaseLogger(__name__)

# TODO: This entire module is incomplete and not used.


# Generic save function
def generic_save_results(ARG_function: Callable, ARG_filetype: str = "txt"):
    """Asks the user to see if they want to save the results of a function, and proceeds accordingly."""
    do_we_save: bool = dialogsave.prompt_save_yesno()
    if do_we_save is False:
        ARG_function()
    else:
        pass


# Generic save function
def generic_save_changes():
    """NOT YET IMPLEMENTED. Asks the user if they want to save changes to a file, and proceeds accordingly."""
    raise NotImplementedError
Пример #9
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# messages.py
# rosevomit.programcli.messages
# ___________________________________________________________________
"""Contains system messages to display to users."""
from core import about, logs
from programcli import formatting

_MESSAGE_LOGGER = logs.BaseLogger(__name__)


# ---------- Standard messages ----------
def general_program_message(ARG_string: str):
    """A generic message. Displays a textwrapped message, and then 'Press Enter to Continue.' The user can then press enter.

    Parameters
    ----------
    ARG_string : str
        The message contents to display.
    """
    print()
    formatting.printwrap(f"{ARG_string} Press 'Enter' to continue.")
    input()


def unrecognized_input_message(ARG_input):
    """Displays a message saying 'Sorry, ARG_input isn't a recognized command in this menu/dialog.'
    
    Parameters
    ----------
Пример #10
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# directories.py
# rosevomit.core.directories
# ___________________________________________________________________
"""This file contains the 'get_dir' function, which should theoretically be able to find any subdirectory of the Rosevomit directory from anywhere within the 'rosevomit' module or the associated repository. Theoretically."""
import glob
import os
import pathlib

from core import logs
from core.customerrors import RealityError

_DIRECTORIESLOGGER = logs.BaseLogger(__name__)


def get_cwd_name_only() -> str:
    """Returns only the folder name of the current working directory, not the full path.

    Returns
    -------
    str
        The name of the current working directory.
    """
    _cwd = pathlib.Path.cwd()
    _path_split = os.path.split(_cwd)
    return _path_split[-1]


def get_dir(ARG_dirname: str) -> pathlib.Path:
    """Returns the path of subdirectory of the 'rosevomit' directory. This function should work anywhere within the 'rosevomit' module or the associated repository.
Пример #11
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# startup.py
# rosevomit.core.startup
# ___________________________________________________________________
"""The setup utility file for Alex's "Project ROSEVOMIT", a random name generator  and random timeline generator written in Python."""
from core import logs
from core.constants import MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION, IS_DEVBUILD
from core.utilities import debugmessage
from programcli import messages

_STARTUPLOGGER = logs.BaseLogger(__name__)


def main_setup():
    """Contains setup instructions, and prints that info to terminal. Accepts no parameters, returns nothing."""
    _STARTUPLOGGER.logger.debug("Starting main setup procedure.")
    print()

    if int(MAJOR_VERSION) >= 1 and IS_DEVBUILD:
        messages.warning_version_is_devbuild()
    elif int(MAJOR_VERSION) < 1:
        if IS_DEVBUILD:
            messages.warning_version_is_prerelease_devbuild(
                MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION)
        else:
            messages.warning_version_is_prerelease(MAJOR_VERSION,
                                                   MINOR_VERSION,
                                                   PATCH_VERSION)

    messages.general_program_message(
Пример #12
0
import os
import textwrap

try:
    from core import logs, customerrors, constants
    import core.utilities as ut
    from programcli import dialogsave
    from programlogic import suncalc, randomevent, randomname
except ImportError:
    from rosevomit.core import logs, customerrors, constants
    import rosevomit.core.utilities as ut
    from rosevomit.programcli import dialogsave
    from rosevomit.programlogic import suncalc, randomevent, randomname


_LOGICLOGGER = logs.BaseLogger (__name__)


def generate_names (ARG_nametype: str, ARG_number: int):
    """This function generates a number of random names.

    Parameters
    ----------
    ARG_nametype : str
        Valid nametypes are 'first', 'firstfemale', 'firstmale', 'last', 'full', 'fullfemale', 'fullmale'.
    ARG_number : int
        The number of names to generate.
    """
    if ARG_nametype == "first":
        ut.repeat (randomname.getname_firstany, ARG_number)
    elif ARG_nametype == "firstfemale":
Пример #13
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# antikythera_time.py
# rosevomit.programlogic.antikythera_time
# ___________________________________________________________________
"""A file containing functions related to Antikythera's date/time/calendars."""
from decimal import Decimal

from core import logs
from core.utilities import validate_range

_TIMETRACKER = logs.BaseLogger(__name__)


def time2fractday(ARG_day: int,
                  ARG_hour: int = 0,
                  ARG_minute: int = 0,
                  ARG_second: int = 0):
    """This function accepts arguments for a given time (day, hour, minute, and second) of the year, and returns the equivalent fractional day.

    Parameters
    ----------
    ARG_day : int
        The day of the year of the desired fractional date, from 1 to 365.
    ARG_hour, ARG_minute, ARG_second : int (default is 0)
        The hour, minute, and second of the desired fractional date. 'ARG_hour' must be between 0 and 23. 'ARG_minute' and 'ARG_second' must be between 0 and 59.

    Returns
    -------
    int or Decimal
        The fractional day equivalent to the given day, hour, minute, and second.
Пример #14
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# customerrors.py
# rosevomit.core.customerrors
# ___________________________________________________________________
"""Currently a placeholder file."""
from core import logs

_CUSTOMERRORSLOGGER = logs.BaseLogger(__name__)


class RealityError(Exception):
    """These things should not happen.

    Upon __init__, pass *args and **kwargs to Exception (superclass).

    Parameters
    ----------
    *args
        A varying number of positional arguments.
    **kwargs
        A varying number of named (keyworded) arguments.
    """
    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)
Пример #15
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# suncalc.py
# rosevomit.programlogic.suncalc
# ___________________________________________________________________
"""A file that contains functions for calculating the position across Antikythera, dependinging on the time and date."""
from decimal import Decimal
import operator
import os
import time

from core import logs
from core.constants import SAVE_DIRECTORY_PATH
from programlogic import antikythera_time, suncalc_helpers

_SUNCALCLOGGER = logs.BaseLogger(__name__)


def main(ARG_lat, ARG_long, ARG_output_file="results"):
    """The main suncalc function.
    Parameters
    ----------
    lat, long
        The observer's coordinates, measured in degrees (°).
    ARG_output_directory (default is None)
        The default directoryto save results in.
    ARG_output_file (default is "results")
        The default name (minus the extension) to be used when naming the save file.
    """
    lat = Decimal(ARG_lat)
    long = Decimal(ARG_long)
Пример #16
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# formatting.py
# rosevomit.programcli.formatting
# ___________________________________________________________________
"""A file containing functions used for the formatting of output messages."""
import textwrap

from core import logs

_FORMATTING_LOGGER = logs.BaseLogger(__name__)


def printwrap(x, ARG_indented: bool = False, ARG_end_with: str = '\n'):
    """Textwrapping for regular 'print' commands.

    Parameters
    ----------
    x
        The text to be wrapped.
    ARG_indented : bool (default is 'False')
        Whether or not the textwrapped string should be indented.
    ARG_end_with : str (default is '\n')
        The string that the textwrapped string will end with.
    """
    if ARG_indented is True:
        print(textwrap.fill(x, width=70, subsequent_indent="   "),
              end=ARG_end_with)
    else:
        print(textwrap.fill(x, width=70), end=ARG_end_with)
Пример #17
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# exiting.py
# rosevomit.programlogic.exiting
# ___________________________________________________________________
"""This file handles Rosevomit's exiting behavior."""
import sys

from core import logs, settings, tempfiles
from programcli import dialogexit

EXITLOGGER = logs.BaseLogger (__name__)

def exit_rosevomit():
    """Handles Rosevomit's exit behavior. Accepts nothing, returns nothing."""
    do_temp_files_exist: bool = not tempfiles.is_empty()  # The 'not' operator effectively reverses the boolean returned from tempfiles.is_empty()
    always_show_exit_dialog: bool = settings.exit_dialog()
    autoclean_temp_directory: bool = settings.autoclean_temp_directory()

    if do_temp_files_exist is True and autoclean_temp_directory is True:
        tempfiles.delete()

    if always_show_exit_dialog is True:
        dialogexit.simple_exit_dialog()  # "Are you sure you want to exit?"
    else:
        EXITLOGGER.logger.critical ("Exiting ROSEVOMIT.")
        sys.exit(0)
Пример #18
0
# This Python file uses the following encoding: utf-8
# ___________________________________________________________________
# dialogsave.py
# rosevomit.programcli.dialogsave
# ___________________________________________________________________
"""A UI module that contains the dialog for saving files."""
import typing

import core.utilities as ut
from core import logs, tempfiles
from programcli import _dialog, formatting, messages

_SAVE_DIALOG_LOGGER = logs.BaseLogger(__name__)


def prompt_save_yesno(ARG_filename: str = "") -> bool:
    """Asks the user if they want to save ARG_file. Basically a convenient wrapper around prompt_yesno().

    Parameters
    ----------
    ARG_filename : str
        The name of the file that the user will be asked if they want to save.

    Returns
    -------
    bool
        If the user wants to save 'ARG_file", this returns 'True'. Else, 'False'.
    """
    if ARG_filename == "":
        result = _dialog.prompt_yesno("Do you want to save the results? ")
    else:
Пример #19
0
# worsecli.py
# rosevomit.programcli.worsecli
# ___________________________________________________________________
"""A UI module that contains functions for displaying menus beyond Rosevomits's main menu, and for processing the inputs for those menus.

WILL BE REPLACED EVENTUALLY BY rosevomit.programcli.bettercli
"""
import re

from programcli import messages
from core import logs, settings
from programlogic import logiccontroller, exiting

_WORSECLI_LOGGER = logs.BaseLogger (__name__)


def input_integer(ARG_prompt_text: str="", ARG_if_invalid=None):
    """Prompts the user for an integer, and checks to make sure that the user's input is actually an integer. If it is, it returns the integer. If it is not, it informs the user of the invalid input and prompts them again for valid input or runs the function passed to it through the 'ARG_if_invalid' argument."""
    _prompt = ARG_prompt_text.strip()
    if _prompt == "" or _prompt is None:
        _input = input ("Please enter a positive integer: ")
    else:
        _input = input (f"{_prompt} ")
    _input = _input.strip()
    try:
        _input = abs (int (_input))
        return _input
    except ValueError:
        print ("Sorry, that's not a valid number.")
        if ARG_if_invalid == "" or ARG_if_invalid is None:
            recursive_result = input_integer(_prompt)
Пример #20
0
WORK IN PROGRESS.
"""
import cmd  # "Simple framework for writing CLIs"
import shlex  # "Lexical analysis for simple syntaxes resembling Unix shell"
import sys  # "System-specific parameters and functions"
if sys.platform in ("win32", "cygwin"):
    try:
        import pyreadline  # "A Python implementation of GNU readline" (necessary for autocomplete)
    except ImportError:
        raise ImportError("Please install the 'pyreadline' module from pypi.")
else:
    import readline  # Available as part of the standard library on most non-Windows systems.

from core import logs

_BETTERCLI_LOGGER = logs.BaseLogger (__name__)


class CLIv2(cmd.Cmd):
    """Creates instance of 'Cmd' framework, which we modify."""
    intro = "Starting CLIv2 prompt..."
    prompt = "> "
    # ----- Quick guide to Cmd -----
    # Any method we define below using the 'do_*' prefix will be interpreted by Cmd as a command it can offer the user. Anything the user types following a recognized command (before pressing 'enter') is passed to that command's 'do_*' method via the ARG_user_input parameter. If I want cool parsing functionality, then I need to build it around each method's ARG_user_input parameter. If the user requests help-text for the command, then that help-text is either automatically generated via a docstring or using the corresponding method with a 'help_*' prefix. The benefit of having an explicit 'help_*' method instead of a docstring is that, while Cmd already has a solid foundation of built-in ways for the user to request help-text, adding additional ways for the user to request help-text is easier when I have a help function to point to.
    # Additionally: I suspect (but have not tested) that if both a docstring and a matching 'help_*' method are available, Cmd will use the 'help_*' method to generate the help-text. Just something I should keep in mind.

    def do_about_program(self, ARG_user_input):
        """Displays version and license information about the program."""
        if ARG_user_input == "?":
            return self.help_about_program()
        else: