# 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
# 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)
# 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'. """
# 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
# 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.", )
# 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 = [
# ___________________________________________________________________ # 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 -------
# 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
# 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 ----------
# 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.
# 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(
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":
# 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.
# 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)
# 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)
# 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)
# 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)
# 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:
# 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)
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: